parent
f99790b1a5
commit
7a636fb496
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use App\Models\Setting;
|
||||||
|
|
||||||
|
class SpamAvCollectCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'spamav:collect';
|
||||||
|
protected $description = 'Collect Rspamd/ClamAV metrics and persist to Settings (DB→Redis)';
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$this->info('Collecting Spam/AV metrics…');
|
||||||
|
|
||||||
|
$collect = function (): array {
|
||||||
|
$out = trim(@shell_exec('rspamc counters 2>/dev/null') ?? '');
|
||||||
|
$ham = preg_match('/\bham\s*:\s*(\d+)/i', $out, $m1) ? (int)$m1[1] : 0;
|
||||||
|
$spam = preg_match('/\bspam\s*:\s*(\d+)/i', $out, $m2) ? (int)$m2[1] : 0;
|
||||||
|
$reject = preg_match('/\breject\s*:\s*(\d+)/i', $out, $m3) ? (int)$m3[1] : 0;
|
||||||
|
|
||||||
|
$rspamdVer = trim(@shell_exec('rspamadm version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
$clamVer = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
|
||||||
|
$sigUpdated = null;
|
||||||
|
$log = @shell_exec('grep -i "Database updated" /var/log/clamav/freshclam.log | tail -n1 2>/dev/null');
|
||||||
|
if ($log) { $sigUpdated = trim($log); }
|
||||||
|
|
||||||
|
return compact('ham','spam','reject','rspamdVer','clamVer','sigUpdated') + ['ts' => time()];
|
||||||
|
};
|
||||||
|
|
||||||
|
$data = $collect();
|
||||||
|
Setting::set('spamav.metrics', $data);
|
||||||
|
Cache::put('dash.spamav', $data, 60);
|
||||||
|
|
||||||
|
$this->info(sprintf(
|
||||||
|
'ham=%d spam=%d reject=%d | rspamd=%s | clam=%s',
|
||||||
|
$data['ham'], $data['spam'], $data['reject'], $data['rspamdVer'], $data['clamVer']
|
||||||
|
));
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Livewire\Ui\Security;
|
||||||
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use App\Models\Setting;
|
||||||
|
|
||||||
class SpamAvCard extends Component
|
class SpamAvCard extends Component
|
||||||
{
|
{
|
||||||
|
|
@ -14,30 +15,122 @@ class SpamAvCard extends Component
|
||||||
public string $clamVer = '–';
|
public string $clamVer = '–';
|
||||||
public ?string $sigUpdated = null;
|
public ?string $sigUpdated = null;
|
||||||
|
|
||||||
public function mount(): void { $this->load(); }
|
// wie frisch müssen Zahlen mindestens sein (Sek.)
|
||||||
public function render() { return view('livewire.ui.security.spam-av-card'); }
|
protected int $maxAge = 300;
|
||||||
public function refresh(): void { $this->load(true); }
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.ui.security.spam-av-card');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refresh(): void
|
||||||
|
{
|
||||||
|
$this->load(true);
|
||||||
|
}
|
||||||
|
|
||||||
protected function load(bool $force = false): void
|
protected function load(bool $force = false): void
|
||||||
{
|
{
|
||||||
$data = Cache::remember('dash.spamav', $force ? 1 : 60, function () {
|
// 1) Versuche erst aus Settings (DB/Redis), optional mit Cache-Shortcuts
|
||||||
$out = trim(@shell_exec('rspamc counters 2>/dev/null') ?? '');
|
$data = $force ? null : Cache::get('dash.spamav');
|
||||||
// very rough counters (adapt to your setup)
|
|
||||||
$ham = preg_match('/ham:\s*(\d+)/i', $out, $m1) ? (int)$m1[1] : 0;
|
|
||||||
$spam = preg_match('/spam:\s*(\d+)/i', $out, $m2) ? (int)$m2[1] : 0;
|
|
||||||
$reject = preg_match('/reject:\s*(\d+)/i', $out, $m3) ? (int)$m3[1] : 0;
|
|
||||||
|
|
||||||
$rspamdVer = trim(@shell_exec('rspamadm version 2>/dev/null') ?? '') ?: '–';
|
if (!$data) {
|
||||||
$clamVer = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '–';
|
$data = Setting::get('spamav.metrics');
|
||||||
|
}
|
||||||
|
|
||||||
// last signatures update (freshclam log)
|
// 2) Wenn keine Daten oder zu alt ⇒ neu sammeln
|
||||||
$sigUpdated = null;
|
$stale = !is_array($data) || (time() - (int)($data['ts'] ?? 0) > $this->maxAge);
|
||||||
$log = @shell_exec('grep -i "Database updated" /var/log/clamav/freshclam.log | tail -n1 2>/dev/null');
|
if ($force || $stale) {
|
||||||
if ($log) $sigUpdated = trim($log);
|
$data = $this->collectMetrics();
|
||||||
|
// Persistenz: Settings (DB→Redis) + UI-Cache (kurz)
|
||||||
|
Setting::set('spamav.metrics', $data);
|
||||||
|
Cache::put('dash.spamav', $data, 60);
|
||||||
|
}
|
||||||
|
|
||||||
return compact('ham','spam','reject','rspamdVer','clamVer','sigUpdated');
|
// 3) Auf Properties mappen
|
||||||
});
|
$this->ham = (int)($data['ham'] ?? 0);
|
||||||
|
$this->spam = (int)($data['spam'] ?? 0);
|
||||||
|
$this->reject = (int)($data['reject'] ?? 0);
|
||||||
|
$this->rspamdVer = (string)($data['rspamdVer'] ?? '–');
|
||||||
|
$this->clamVer = (string)($data['clamVer'] ?? '–');
|
||||||
|
$this->sigUpdated = $data['sigUpdated'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($data as $k => $v) $this->$k = $v;
|
/** Sammelt live von rspamd/clamav – robust und schnell */
|
||||||
|
protected function collectMetrics(): array
|
||||||
|
{
|
||||||
|
// rspamd counters
|
||||||
|
$out = trim(@shell_exec('rspamc counters 2>/dev/null') ?? '');
|
||||||
|
$ham = preg_match('/\bham\s*:\s*(\d+)/i', $out, $m1) ? (int)$m1[1] : 0;
|
||||||
|
$spam = preg_match('/\bspam\s*:\s*(\d+)/i', $out, $m2) ? (int)$m2[1] : 0;
|
||||||
|
$reject = preg_match('/\breject\s*:\s*(\d+)/i', $out, $m3) ? (int)$m3[1] : 0;
|
||||||
|
|
||||||
|
// Versionen
|
||||||
|
$rspamdVer = trim(@shell_exec('rspamadm version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
$clamVer = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
|
||||||
|
// Letztes Signatur-Update aus freshclam.log
|
||||||
|
$sigUpdated = null;
|
||||||
|
$log = @shell_exec('grep -i "Database updated" /var/log/clamav/freshclam.log | tail -n1 2>/dev/null');
|
||||||
|
if ($log) {
|
||||||
|
$sigUpdated = trim($log);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ts' => time(),
|
||||||
|
'ham' => $ham,
|
||||||
|
'spam' => $spam,
|
||||||
|
'reject' => $reject,
|
||||||
|
'rspamdVer' => $rspamdVer,
|
||||||
|
'clamVer' => $clamVer,
|
||||||
|
'sigUpdated' => $sigUpdated,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//namespace App\Livewire\Ui\Security;
|
||||||
|
//
|
||||||
|
//use Livewire\Component;
|
||||||
|
//use Illuminate\Support\Facades\Cache;
|
||||||
|
//
|
||||||
|
//class SpamAvCard extends Component
|
||||||
|
//{
|
||||||
|
// public int $ham = 0;
|
||||||
|
// public int $spam = 0;
|
||||||
|
// public int $reject = 0;
|
||||||
|
// public string $rspamdVer = '–';
|
||||||
|
// public string $clamVer = '–';
|
||||||
|
// public ?string $sigUpdated = null;
|
||||||
|
//
|
||||||
|
// public function mount(): void { $this->load(); }
|
||||||
|
// public function render() { return view('livewire.ui.security.spam-av-card'); }
|
||||||
|
// public function refresh(): void { $this->load(true); }
|
||||||
|
//
|
||||||
|
// protected function load(bool $force = false): void
|
||||||
|
// {
|
||||||
|
// $data = Cache::remember('dash.spamav', $force ? 1 : 60, function () {
|
||||||
|
// $out = trim(@shell_exec('rspamc counters 2>/dev/null') ?? '');
|
||||||
|
// // very rough counters (adapt to your setup)
|
||||||
|
// $ham = preg_match('/ham:\s*(\d+)/i', $out, $m1) ? (int)$m1[1] : 0;
|
||||||
|
// $spam = preg_match('/spam:\s*(\d+)/i', $out, $m2) ? (int)$m2[1] : 0;
|
||||||
|
// $reject = preg_match('/reject:\s*(\d+)/i', $out, $m3) ? (int)$m3[1] : 0;
|
||||||
|
//
|
||||||
|
// $rspamdVer = trim(@shell_exec('rspamadm version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
// $clamVer = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '–';
|
||||||
|
//
|
||||||
|
// // last signatures update (freshclam log)
|
||||||
|
// $sigUpdated = null;
|
||||||
|
// $log = @shell_exec('grep -i "Database updated" /var/log/clamav/freshclam.log | tail -n1 2>/dev/null');
|
||||||
|
// if ($log) $sigUpdated = trim($log);
|
||||||
|
//
|
||||||
|
// return compact('ham','spam','reject','rspamdVer','clamVer','sigUpdated');
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// foreach ($data as $k => $v) $this->$k = $v;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,9 @@ class UpdateCard extends Component
|
||||||
if ($this->rc === 0 && !$this->postActionsDone) {
|
if ($this->rc === 0 && !$this->postActionsDone) {
|
||||||
// Dienste neu starten (asynchron)
|
// Dienste neu starten (asynchron)
|
||||||
@shell_exec('nohup php /var/www/mailwolt/artisan mailwolt:restart-services >/dev/null 2>&1 &');
|
@shell_exec('nohup php /var/www/mailwolt/artisan mailwolt:restart-services >/dev/null 2>&1 &');
|
||||||
|
@shell_exec('nohup php /var/www/mailwolt/artisan settings:sync >/dev/null 2>&1 &');
|
||||||
|
@shell_exec('nohup php /var/www/mailwolt/artisan spamav:collect >/dev/null 2>&1 &');
|
||||||
|
|
||||||
$this->postActionsDone = true;
|
$this->postActionsDone = true;
|
||||||
|
|
||||||
$ver = $this->displayCurrent ?? 'aktuelle Version';
|
$ver = $this->displayCurrent ?? 'aktuelle Version';
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ Artisan::command('inspire', function () {
|
||||||
$this->comment(Inspiring::quote());
|
$this->comment(Inspiring::quote());
|
||||||
})->purpose('Display an inspiring quote');
|
})->purpose('Display an inspiring quote');
|
||||||
|
|
||||||
Schedule::job(RunHealthChecks::class)->everyMinute()->withoutOverlapping();
|
Schedule::job(RunHealthChecks::class)->everyFiveMinutes()->withoutOverlapping();
|
||||||
//Schedule::command('woltguard:collect-services')->everyMinute();
|
Schedule::command('spamav:collect')->everyFiveMinutes()->withoutOverlapping();
|
||||||
//Schedule::command('mailwolt:check-updates')->dailyAt('04:10');
|
//Schedule::command('mailwolt:check-updates')->dailyAt('04:10');
|
||||||
Schedule::command('mailwolt:check-updates')->everytwoMinutes();
|
Schedule::command('mailwolt:check-updates')->everytwoMinutes();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue