diff --git a/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php b/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php index b6a9568..778caa1 100644 --- a/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php +++ b/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php @@ -91,37 +91,27 @@ class Fail2BanJailModal extends ModalComponent /** letzte "Ban "-Zeile -> Unix-Timestamp (robust über zgrep/journal/jail-tail) */ private function lastBanTimestamp(string $jail, string $ip): ?int { - // 1) zgrep über alle Logfiles (inkl. Rotation .N und .gz) - $j = escapeshellarg($jail); - $p = escapeshellarg($ip); - $cmd = "zgrep -h \"[${jail}] Ban ${ip}\" /var/log/fail2ban.log* 2>/dev/null | tail -n 1"; - $line = trim((string) @shell_exec($cmd)); + $sudo = '/usr/bin/sudo'; + $zgrep = '/usr/bin/zgrep'; + $journal = '/usr/bin/journalctl'; + $tail = '/usr/bin/tail'; - // 2) Fallback: journald der letzten 14 Tage - if ($line === '') { - $cmdJ = "journalctl -u fail2ban --since '14 days ago' 2>/dev/null | grep -F \"[{$jail}] Ban {$ip}\" | tail -n 1"; - $line = trim((string) @shell_exec($cmdJ)); - } + $needle = sprintf('[%s] Ban %s', $jail, $ip); + $q = escapeshellarg($needle); - // 3) Fallback: PHP-Tail nur aktuelles file + // 1) zgrep über alle fail2ban-Logs (inkl. Rotation .N, .gz) + $cmd1 = "$sudo -n $zgrep -h $q /var/log/fail2ban.log* 2>/dev/null | $tail -n 1"; + $line = trim((string)@shell_exec($cmd1)); + + // 2) Fallback: journald (ohne grep-Pipe, mit -g) if ($line === '') { - $file = '/var/log/fail2ban.log'; - if (!is_readable($file)) return null; - $tailBytes = 400000; - $size = @filesize($file) ?: 0; - $seek = max(0, $size - $tailBytes); - $fh = @fopen($file, 'rb'); if (!$fh) return null; - if ($seek > 0) fseek($fh, $seek); - $data = stream_get_contents($fh) ?: ''; - fclose($fh); - if (preg_match('/^.*\['.preg_quote($jail,'/').'\]\s+Ban\s+'.preg_quote($ip,'/').'.*$/m', $data, $m)) { - $line = trim($m[0]); - } + $cmd2 = "$sudo -n $journal -u fail2ban --since '14 days ago' --no-pager -g $q 2>/dev/null | $tail -n 1"; + $line = trim((string)@shell_exec($cmd2)); } if ($line === '') return null; - // Zeitstempel irgendwo in der Zeile (ISO-ähnlich) nehmen + // Zeitstempel extrahieren (YYYY-MM-DD HH:MM:SS) if (preg_match('/(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})/', $line, $m)) { $ts = strtotime($m[1].' '.$m[2]); return $ts ?: null;