89 lines
2.9 KiB
PHP
89 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire\Ui\Security;
|
||
|
||
use Livewire\Component;
|
||
|
||
class Fail2BanCard extends Component
|
||
{
|
||
public bool $available = true;
|
||
public bool $permDenied = false; // neu
|
||
public int $activeBans = 0;
|
||
public array $jails = [];
|
||
public array $topIps = [];
|
||
|
||
// ...
|
||
|
||
protected function load(bool $force = false): void
|
||
{
|
||
$bin = trim((string) @shell_exec('command -v fail2ban-client 2>/dev/null')) ?: '';
|
||
if ($bin === '') {
|
||
$this->available = false;
|
||
$this->permDenied = false;
|
||
$this->activeBans = 0;
|
||
$this->jails = [];
|
||
$this->topIps = [];
|
||
return;
|
||
}
|
||
|
||
// ping → prüft zugleich Rechte (liefert Fehlertext, wenn Socket gesperrt)
|
||
[$ok, $raw] = $this->f2b('ping'); // ok==true wenn "pong"
|
||
|
||
if (!$ok && stripos($raw, 'permission denied') !== false) {
|
||
$this->available = true;
|
||
$this->permDenied = true;
|
||
$this->activeBans = 0;
|
||
$this->jails = [];
|
||
$this->topIps = $this->collectTopIps();
|
||
return;
|
||
}
|
||
|
||
// Jails
|
||
[, $status] = $this->f2b('status');
|
||
$jailsLn = $this->firstMatch('/Jail list:\s*(.+)$/mi', $status);
|
||
$jails = $jailsLn ? array_filter(array_map('trim', preg_split('/\s*,\s*/', $jailsLn))) : [];
|
||
|
||
$total = 0; $rows = [];
|
||
foreach ($jails as $j) {
|
||
[, $s] = $this->f2b('status '.escapeshellarg($j));
|
||
$banned = (int) ($this->firstMatch('/Currently banned:\s+(\d+)/i', $s) ?: 0);
|
||
$ipList = $this->firstMatch('/Banned IP list:\s*(.+)$/mi', $s) ?: '';
|
||
$ips = $ipList !== '' ? array_values(array_filter(array_map('trim', preg_split('/\s+/', $ipList)))) : [];
|
||
$rows[] = ['name'=>$j,'banned'=>$banned,'ips'=>array_slice($ips, 0, 8)];
|
||
$total += $banned;
|
||
}
|
||
|
||
$this->available = true;
|
||
$this->permDenied = false;
|
||
$this->activeBans = $total;
|
||
$this->jails = $rows;
|
||
$this->topIps = $this->collectTopIps();
|
||
}
|
||
|
||
/** führt fail2ban-client aus; mit sudo-Fallback; gibt [ok, output] zurück */
|
||
private function f2b(string $args): array
|
||
{
|
||
$sudo = '/usr/bin/sudo';
|
||
$f2b = '/usr/bin/fail2ban-client';
|
||
$cmd = "timeout 2 $sudo -n $f2b $args 2>&1";
|
||
$out = (string) @shell_exec($cmd);
|
||
|
||
$ok = stripos($out, 'Status') !== false
|
||
|| stripos($out, 'Jail list') !== false
|
||
|| stripos($out, 'pong') !== false;
|
||
|
||
return [$ok, $out];
|
||
}
|
||
|
||
private function firstMatch(string $pattern, string $haystack): ?string
|
||
{
|
||
return preg_match($pattern, $haystack, $m) ? trim($m[1]) : null;
|
||
}
|
||
|
||
private function collectTopIps(): array
|
||
{
|
||
// … (deine vorhandene Methode aus meiner letzten Antwort – passt)
|
||
// lässt du unverändert.
|
||
}
|
||
}
|