Fix: Fail2ban Restzeit via Python3-Script statt sqlite3-CLI (nicht installiert)

main v1.1.425
boban 2026-04-27 05:20:10 +02:00
parent 3e157f4e56
commit ff28b98555
3 changed files with 40 additions and 37 deletions

View File

@ -4,7 +4,6 @@ namespace App\Livewire\Ui\Security;
use Livewire\Attributes\On;
use Livewire\Component;
use SQLite3;
class Fail2banBanlist extends Component
{
@ -135,23 +134,10 @@ class Fail2banBanlist extends Component
/** Gibt permanent-Flag und verbleibende Zeit für (jail, ip) zurück. */
private function getBanInfo(string $jail, string $ip): array
{
$db = $this->getDbFile();
$fallbackPermanent = ($jail === 'mailwolt-blacklist');
if ($db === '') {
return ['permanent' => $fallbackPermanent, 'remaining' => ''];
}
$q = sprintf(
"WITH last AS (SELECT MAX(timeofban) AS t FROM bans WHERE jail='%s' AND ip='%s') ".
"SELECT timeofban, bantime FROM bans, last ".
"WHERE jail='%s' AND ip='%s' AND timeofban=last.t LIMIT 1;",
SQLite3::escapeString($jail), SQLite3::escapeString($ip),
SQLite3::escapeString($jail), SQLite3::escapeString($ip)
);
$cmd = sprintf('sudo -n /usr/bin/sqlite3 -readonly %s %s 2>&1',
escapeshellarg($db), escapeshellarg($q));
$cmd = sprintf('sudo -n /usr/local/sbin/clubird-f2b-baninfo %s %s 2>&1',
escapeshellarg($jail), escapeshellarg($ip));
$out = trim((string)@shell_exec($cmd));
if ($out !== '') {
@ -221,13 +207,4 @@ class Fail2banBanlist extends Component
return (string) @shell_exec('sudo -n /usr/bin/fail2ban-client '.$args.' 2>&1');
}
/** Pfad zur Fail2Ban-SQLite-DB holen */
private function getDbFile(): string
{
$out = $this->f2b('get dbfile');
$lines = array_values(array_filter(array_map('trim', preg_split('/\r?\n/', $out))));
$path = end($lines) ?: '';
$path = preg_replace('/^`?-?\s*/', '', $path);
return $path ?: '/var/lib/fail2ban/fail2ban.sqlite3';
}
}

View File

@ -0,0 +1,26 @@
#!/usr/bin/env python3
"""Read ban timing from fail2ban SQLite — called via sudo by www-data."""
import sqlite3, sys, os
if len(sys.argv) < 3:
sys.exit(1)
jail = sys.argv[1]
ip = sys.argv[2]
db = '/var/lib/fail2ban/fail2ban.sqlite3'
if not os.path.isfile(db):
sys.exit(1)
try:
conn = sqlite3.connect(f'file:{db}?mode=ro', uri=True)
cur = conn.execute(
'SELECT timeofban, bantime FROM bans WHERE jail=? AND ip=? ORDER BY timeofban DESC LIMIT 1',
(jail, ip)
)
row = cur.fetchone()
conn.close()
if row:
print(f'{row[0]}|{row[1]}')
except Exception:
sys.exit(1)

View File

@ -286,21 +286,21 @@ UNIT
# Fail2Ban: Jails + Sudoers sicherstellen (idempotent)
local F2B_SUDO="/etc/sudoers.d/clubird-fail2ban"
local F2B_JAIL="/etc/fail2ban/jail.d/clubird-jails.local"
_sbin_install "${APP_DIR}/scripts/clubird-f2b-baninfo" /usr/local/sbin/clubird-f2b-baninfo
if command -v fail2ban-client >/dev/null 2>&1; then
# Sudoers für www-data
# Sudoers idempotent befüllen (fehlende Einträge werden nachgetragen)
if [[ ! -f "$F2B_SUDO" ]]; then
cat > "$F2B_SUDO" << 'SUDOEOF'
www-data ALL=(root) NOPASSWD: /usr/bin/tee /etc/fail2ban/jail.d/00-defaults.local
www-data ALL=(root) NOPASSWD: /usr/bin/tee /etc/fail2ban/jail.d/whitelist.local
www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client reload
www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client status
www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client status *
www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client set * banip *
www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client set * unbanip *
SUDOEOF
chmod 440 "$F2B_SUDO"
echo "[✓] Fail2Ban sudoers installiert."
touch "$F2B_SUDO"; chmod 440 "$F2B_SUDO"
fi
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/tee /etc/fail2ban/jail.d/00-defaults.local'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/tee /etc/fail2ban/jail.d/whitelist.local'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client reload'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client status'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client status *'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client set * banip *'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client set * unbanip *'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/bin/fail2ban-client get *'
_sudoers_add "$F2B_SUDO" 'www-data ALL=(root) NOPASSWD: /usr/local/sbin/clubird-f2b-baninfo *'
# Jail-Konfiguration (dovecot, postfix, nginx)
if [[ ! -f "$F2B_JAIL" ]]; then
cat > "$F2B_JAIL" << 'JAILEOF'