mailwolt/app/Console/Commands/SpamAvCollectCommand.php

141 lines
5.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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…');
$rpC = '/usr/bin/rspamc';
$rpA = '/usr/bin/rspamadm';
// --- RSPAMD: erst 'stat' (sicher), sonst 'counters' als Fallback ---
$ham = $spam = $reject = 0;
$stat = trim(@shell_exec("$rpC -h 127.0.0.1:11334 stat 2>/dev/null") ?? '');
if ($stat !== '') {
$ham = preg_match('/Messages treated as ham:\s*(\d+)/i', $stat, $m) ? (int)$m[1] : 0;
$spam = preg_match('/Messages treated as spam:\s*(\d+)/i', $stat, $m) ? (int)$m[1] : 0;
$reject = preg_match('/Messages with action reject:\s*(\d+)/i', $stat, $m) ? (int)$m[1] : 0;
} else {
$cnt = trim(@shell_exec("$rpC -h 127.0.0.1:11334 counters 2>/dev/null") ?? '');
$ham = preg_match('/\bham\s*:\s*(\d+)/i', $cnt, $m) ? (int)$m[1] : 0;
$spam = preg_match('/\bspam\s*:\s*(\d+)/i', $cnt, $m) ? (int)$m[1] : 0;
$reject = preg_match('/\breject\s*:\s*(\d+)/i', $cnt, $m) ? (int)$m[1] : 0;
}
// Rspamd Version
$rspamdVer = trim(@shell_exec("$rpA --version 2>/dev/null") ?? '');
if ($rspamdVer === '') {
$rspamdVer = trim(@shell_exec("dpkg-query -W -f='\${Version}\n' rspamd 2>/dev/null") ?? '');
}
// $clamLine = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '';
// $clamVer = $clamLine;
//
// // Versuch, Datum aus der Versionzeile zu ziehen (kein Zugriff auf freshclam.log nötig)
// $sigUpdated = null;
// if (preg_match('#/([^/]+ [0-9]{2} [0-9:]{8} [0-9]{4})$#', $clamLine, $m)) {
// $sigUpdated = $m[1]; // z.B. "Sun Oct 26 09:42:43 2025"
// }
// --- CLAMAV: Versionzeile inkl. Signaturdatum ausgeben ---
$clamLine = trim(@shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null') ?? '') ?: '';
$parts = explode('/', $clamLine, 3);
$clamVer = $parts[0] ?? 'ClamAV';
$sigUpdated = null;
if (isset($parts[2])) {
$sigUpdated = trim($parts[2]);
} else {
// Fallback: journalctl (falls Gruppe adm)
$jl = trim(@shell_exec('journalctl -u freshclam -n 50 --no-pager 2>/dev/null | grep -i "Database updated" | tail -n1') ?? '');
if ($jl) $sigUpdated = $jl;
}
$data = [
'ts' => time(),
'ham' => $ham,
'spam' => $spam,
'reject' => $reject,
'rspamdVer' => $rspamdVer ?: '',
'clamVer' => $clamVer,
'sigUpdated' => $sigUpdated,
];
Setting::set('spamav.metrics', $data);
Cache::put('dash.spamav', $data, now()->addMinutes(10));
$this->info(sprintf(
'ham=%d spam=%d reject=%d | rspamd=%s | clam=%s',
$ham, $spam, $reject, $data['rspamdVer'], $clamVer
));
return self::SUCCESS;
}
}
//
//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…');
//
// // Rspamd counters (kein Root nötig)
// $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;
//
// // ClamAV Version + Signatur-Datum robust ohne Datei-Zugriff
// $clamLine = trim((string) @shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null'));
// $clamVer = $clamLine !== '' ? $clamLine : '';
//
// // Aus clamd/clamscan-Output das Datum am Ende herausziehen (Format: ".../Sun Oct 26 09:42:43 2025")
// $sigUpdated = null;
// if ($clamLine && preg_match('#/([^/]+\d{4})$#', $clamLine, $m)) {
// // $m[1] ist z.B. "Sun Oct 26 09:42:43 2025"
// $sigUpdated = $m[1];
// }
//
// $data = [
// 'ts' => time(),
// 'ham' => $ham,
// 'spam' => $spam,
// 'reject' => $reject,
// 'rspamdVer' => trim((string) @shell_exec('rspamadm version 2>/dev/null')) ?: '',
// 'clamVer' => $clamVer,
// 'sigUpdated' => $sigUpdated,
// ];
//
// // Persistieren (DB→Redis) + kurzer UI-Cache
// 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;
// }
//}