161 lines
5.1 KiB
PHP
161 lines
5.1 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire\Ui\Security;
|
||
|
||
use Livewire\Attributes\Layout;
|
||
use Livewire\Attributes\Title;
|
||
use Livewire\Component;
|
||
|
||
#[Layout('layouts.dvx')]
|
||
#[Title('Virenschutz · Mailwolt')]
|
||
class ClamavManager extends Component
|
||
{
|
||
public bool $installed = false;
|
||
public bool $running = false;
|
||
public bool $enabled = false;
|
||
public string $dbDate = '—';
|
||
public string $dbVersion = '—';
|
||
public ?int $ramMb = null;
|
||
public string $lastError = '';
|
||
public string $lastSuccess = '';
|
||
public bool $installing = false;
|
||
public bool $starting = false;
|
||
|
||
public function mount(): void
|
||
{
|
||
$this->refresh();
|
||
}
|
||
|
||
public function refresh(): void
|
||
{
|
||
$this->lastError = '';
|
||
$this->lastSuccess = '';
|
||
$this->starting = false;
|
||
$this->running = $this->serviceActive();
|
||
$this->enabled = $this->serviceEnabled();
|
||
$this->installed = true;
|
||
$this->ramMb = $this->running ? $this->readRamMb() : null;
|
||
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
|
||
}
|
||
|
||
public function pollStatus(): void
|
||
{
|
||
if (!$this->starting) return;
|
||
$this->running = $this->serviceActive();
|
||
$this->enabled = $this->serviceEnabled();
|
||
if ($this->running) {
|
||
$this->starting = false;
|
||
$this->lastSuccess = 'ClamAV wurde aktiviert und läuft.';
|
||
$this->ramMb = $this->readRamMb();
|
||
}
|
||
}
|
||
|
||
public function install(): void
|
||
{
|
||
$this->installing = true;
|
||
$out = [];
|
||
@exec('sudo -n /usr/local/sbin/mailwolt-clamav install 2>&1', $out, $rc);
|
||
$this->installing = false;
|
||
if ($rc !== 0) {
|
||
$this->lastError = implode(' ', $out) ?: 'Installation fehlgeschlagen.';
|
||
} else {
|
||
$this->dispatch('toast', type: 'success', badge: 'ClamAV',
|
||
title: 'Installiert', text: 'ClamAV wurde installiert. Sie können ihn jetzt aktivieren.');
|
||
}
|
||
$this->refresh();
|
||
}
|
||
|
||
public function enable(): void
|
||
{
|
||
$this->lastError = $this->lastSuccess = '';
|
||
// Im Hintergrund starten – systemctl start kann 30-60s dauern (DB-Laden)
|
||
shell_exec('nohup sudo -n /usr/local/sbin/mailwolt-clamav enable > /tmp/mw-clamav-start.log 2>&1 &');
|
||
$this->starting = true;
|
||
$this->enabled = true; // systemctl enable ist sofort wirksam
|
||
}
|
||
|
||
public function disable(): void
|
||
{
|
||
[$ok, $msg] = $this->runCmd('disable');
|
||
if ($ok) $this->lastSuccess = 'ClamAV wurde gestoppt und deaktiviert.';
|
||
else $this->lastError = $msg;
|
||
$this->running = $this->serviceActive();
|
||
$this->enabled = $this->serviceEnabled();
|
||
}
|
||
|
||
public function updateDb(): void
|
||
{
|
||
[$ok, $msg] = $this->runCmd('freshclam');
|
||
if ($ok) $this->lastSuccess = 'Virensignaturen wurden aktualisiert.';
|
||
else $this->lastError = $msg;
|
||
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
|
||
}
|
||
|
||
private function runCmd(string $action): array
|
||
{
|
||
$out = []; $rc = null;
|
||
exec('sudo -n /usr/local/sbin/mailwolt-clamav ' . escapeshellarg($action) . ' 2>&1', $out, $rc);
|
||
\Log::info('ClamAV ' . $action, ['rc' => $rc, 'out' => $out]);
|
||
$msg = implode(' ', $out) ?: 'Unbekannter Fehler (rc=' . $rc . ')';
|
||
return [$rc === 0, $msg];
|
||
}
|
||
|
||
private function serviceActive(): bool
|
||
{
|
||
$exit = null;
|
||
@exec('systemctl is-active --quiet clamav-daemon 2>/dev/null', $_, $exit);
|
||
return $exit === 0;
|
||
}
|
||
|
||
private function serviceEnabled(): bool
|
||
{
|
||
$exit = null;
|
||
@exec('systemctl is-enabled --quiet clamav-daemon 2>/dev/null', $_, $exit);
|
||
return $exit === 0;
|
||
}
|
||
|
||
private function readRamMb(): ?int
|
||
{
|
||
$out = [];
|
||
@exec("ps -C clamd -o rss= 2>/dev/null", $out);
|
||
$kb = array_sum(array_map('intval', array_filter($out)));
|
||
return $kb > 0 ? (int) round($kb / 1024) : null;
|
||
}
|
||
|
||
private function readDbInfo(): array
|
||
{
|
||
$paths = [
|
||
'/var/lib/clamav/main.cvd',
|
||
'/var/lib/clamav/main.cld',
|
||
'/var/lib/clamav/daily.cvd',
|
||
'/var/lib/clamav/daily.cld',
|
||
];
|
||
$latest = 0;
|
||
foreach ($paths as $p) {
|
||
if (@file_exists($p)) {
|
||
$mtime = @filemtime($p);
|
||
if ($mtime > $latest) $latest = $mtime;
|
||
}
|
||
}
|
||
if ($latest === 0) return ['—', '—'];
|
||
$date = date('d.m.Y H:i', $latest);
|
||
|
||
$ver = '—';
|
||
$out = [];
|
||
@exec('sigtool --info /var/lib/clamav/daily.cld 2>/dev/null | grep "^Version:" | head -1', $out);
|
||
if (empty($out)) {
|
||
@exec('sigtool --info /var/lib/clamav/daily.cvd 2>/dev/null | grep "^Version:" | head -1', $out);
|
||
}
|
||
if (!empty($out[0])) {
|
||
$ver = trim(str_replace('Version:', '', $out[0]));
|
||
}
|
||
|
||
return [$date, $ver];
|
||
}
|
||
|
||
public function render()
|
||
{
|
||
return view('livewire.ui.security.clamav-manager');
|
||
}
|
||
}
|