README and all guides under docs/ are now in German, with German anchors for the cross references. Code and configuration blocks are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 KiB
Agent – f2b-webctl
Auf jedem fail2ban-Host läuft der Agent f2b-webctl: ein kleines
Python-Skript (nur Standardbibliothek), das als SSH-Forced-Command für den Schlüssel der
Weboberfläche gestartet wird. Etwas anderes kann die Weboberfläche auf dem Host nicht ausführen.
| Befehl (von der Weboberfläche) | Wirkung |
|---|---|
list |
alle Jails mit ihren gesperrten IPs (JSON) |
ban <ip> |
dauerhaft im manuellen Jail (manual-block) sperren |
unban <jail> <ip> |
in einem Jail entsperren |
unban-all <ip> |
in allen Jails entsperren |
version |
Agent-Version |
Wird nie gesperrt, egal was die Weboberfläche schickt:
- private, Loopback-, Link-Local-, CGNAT-, Multicast- und reservierte Bereiche
(
10/8,172.16/12,192.168/16,100.64/10,127/8,169.254/16,fc00::/7,fe80::/10, …) - alle Adressen des Hosts selbst und die Adresse, von der die Weboberfläche zugreift
- alles, was unter
PROTECTEDin/etc/f2b-webctl.confsteht (z. B. deine Heim-IP)
Jede Aktion landet im Syslog (Facility auth, Tag f2b-webctl), auch abgelehnte.
Voraussetzungen
| fail2ban | ≥ 0.11, laufend (fail2ban-client ping) – ältere Versionen ohne --with-time funktionieren, aber ohne Start-/Endzeiten |
| python3 | ≥ 3.8 |
| sshd | vom Webui-Host erreichbar |
| sudo | für den Standardbenutzer f2bweb (apt install sudo); mit --user root nicht nötig |
| bash, ssh-keygen | für den Installer |
Läuft auf Debian, Ubuntu, Proxmox VE und anderen Linux-Systemen mit oder ohne systemd – Bare Metal, VMs, LXC-Container (privilegiert oder unprivilegiert) und Docker-Hosts.
Installation
Gebraucht werden der öffentliche Schlüssel aus fail2ban-webui keygen und die Adresse, von
der die Weboberfläche zugreift (öffentliche IP des Docker-Hosts oder seine LAN-Adresse).
# als root auf dem fail2ban-Host
git clone https://git.retronerd.at/schiwagoa/fail2ban-webui.git /tmp/fail2ban-webui
cd /tmp/fail2ban-webui/agent
echo 'ssh-ed25519 AAAA… fail2ban-webui' > /tmp/webui.pub
# anzeigen, was passieren würde
bash install.sh --key-file /tmp/webui.pub --from 198.51.100.10 --dry-run
# installieren
bash install.sh --key-file /tmp/webui.pub --from 198.51.100.10
Ohne git: die drei Dateien f2b-webctl, install.sh und uninstall.sh aus dem Ordner
agent/ in ein Verzeichnis laden und install.sh von dort starten.
Der Installer zeigt eine Zusammenfassung und fragt, bevor er etwas ändert:
fail2ban-webui agent 1.0.0 – fail2ban 1.1.0 – web01
script /usr/local/sbin/f2b-webctl
config /etc/f2b-webctl.conf
SSH user f2bweb (will be created)
sudo rule /etc/sudoers.d/f2b-webctl
key file /var/lib/f2bweb/.ssh/authorized_keys
key 256 SHA256:zfwh… (ED25519)
allowed from 198.51.100.10
manual jail manual-block (will be created)
backups /var/backups/fail2ban-webui-agent
Was er tut:
- sichert jede Datei, die er ändert, nach
--backup-dir - installiert
/usr/local/sbin/f2b-webctl(root:root 0750) - schreibt
/etc/f2b-webctl.conf(bleibt erhalten, wenn sie schon existiert) - legt den Systembenutzer
f2bweban (Home/var/lib/f2bweb, ohne Passwort) und die sudo-RegelDefaults!/usr/local/sbin/f2b-webctl env_keep += "SSH_ORIGINAL_COMMAND SSH_CLIENT" f2bweb ALL=(root) NOPASSWD: /usr/local/sbin/f2b-webctl - trägt den Schlüssel mit allen Einschränkungen ein:
restrict,from="198.51.100.10",command="sudo -n /usr/local/sbin/f2b-webctl" ssh-ed25519 AAAA… fail2ban-webui - legt das Jail
manual-blockan, falls es noch nicht existiert (siehe unten) - führt einen Selbsttest über denselben sudo-Weg aus, den die Weboberfläche nutzt
Den Installer erneut auszuführen ist unbedenklich: Er aktualisiert das Skript, ersetzt den Schlüsseleintrag und lässt deine Konfiguration unverändert.
Optionen
| Option | Standard | Bedeutung |
|---|---|---|
--key-file DATEI / --key "SCHLÜSSEL" |
– | öffentlicher Schlüssel der Weboberfläche (Pflicht) |
--from ADRESSEN |
jede | Schlüssel nur von diesen IPs/Netzen akzeptieren (durch Komma getrennt). Dringend empfohlen. |
--user NAME |
f2bweb |
SSH-Benutzer; root funktioniert ohne sudo |
--authorized-keys-file PFAD |
~USER/.ssh/authorized_keys |
wohin der Schlüsseleintrag kommt – siehe verwaltete Schlüssel |
--manual-jail NAME |
manual-block |
Jail für manuelle Sperren |
--banaction AKTION |
aus jail.local |
Banaction für ein neu angelegtes manuelles Jail |
--protect NETZE |
– | zusätzliche geschützte Adressen (nur wenn die Konfigurationsdatei geschrieben wird) |
--no-jail |
– | kein manuelles Jail anlegen |
--force-config |
– | vorhandene /etc/f2b-webctl.conf überschreiben |
--backup-dir VERZEICHNIS |
/var/backups/fail2ban-webui-agent |
Sicherungen geänderter Dateien |
--dry-run |
– | nur anzeigen, was passieren würde |
-y, --yes |
– | nicht nachfragen |
Der Installer warnt, wenn sshd die gewählte Schlüsseldatei gar nicht liest
(AuthorizedKeysFile), wenn AllowUsers/AllowGroups gesetzt sind oder wenn --user root
auf PermitRootLogin no trifft.
Das manuelle Jail
Sperren aus der Weboberfläche landen in einem Jail, standardmäßig manual-block, mit
bantime = -1 (dauerhaft). Gibt es das Jail noch nicht, legt der Installer an:
/etc/fail2ban/filter.d/manual-block.conf
# fail2ban-webui: never matches – the jail is only filled via
# "fail2ban-client set manual-block banip <ip>"
[Definition]
failregex = ^FAIL2BAN-WEBUI-NEVER-MATCHES <HOST>$
ignoreregex =
/etc/fail2ban/jail.d/manual-block.local
# fail2ban-webui: permanent manual bans from the web UI
[manual-block]
enabled = true
filter = manual-block
backend = polling
logpath = /var/log/fail2ban-manual-block.log
maxretry = 1
bantime = -1
Das Jail nutzt deine Standard-banaction aus jail.local. Sperren überstehen Neustarts
über die fail2ban-Datenbank.
Ein vorhandenes Jail mit diesem Namen wird nie angefasst – gibt es schon ein Jail für
manuelle Sperren, dessen Namen mit --manual-jail übergeben.
Docker-Hosts
Die Standardaktionen von fail2ban sperren in der Kette INPUT. Verkehr zu veröffentlichten
Docker-Ports läuft aber nicht über INPUT, sondern über FORWARD → DOCKER-USER; solche
Sperren würden deine Container also nicht schützen. Auf einem Docker-Host das manuelle Jail
deshalb mit einer Aktion anlegen, die die Kette DOCKER-USER nutzt, z. B. mit iptables:
bash install.sh --key-file /tmp/webui.pub --from 198.51.100.10 \
--banaction "iptables-allports[chain=DOCKER-USER]"
Nach der ersten Sperre prüfen:
iptables -S DOCKER-USER | head
Läuft die Weboberfläche auf demselben Docker-Host, in hosts.yaml address: host.docker.internal
verwenden und SSH aus dem Docker-Netz erlauben, falls eine Firewall (z. B. UFW) es blockiert:
ufw allow from 172.23.51.0/24 to any port 22 proto tcp comment 'fail2ban-webui'
und den Agenten mit --from 172.23.51.10 installieren.
LXC-Container
Der Agent läuft im Container, in dem fail2ban läuft – sonst ist nichts Besonderes nötig. In unprivilegierten Containern muss fail2ban selbst die Firewall des Containers ändern können (nftables/iptables im CT); mit einer manuellen Sperre testen:
fail2ban-client set manual-block banip 203.0.113.1 && nft list ruleset | grep 203.0.113.1
fail2ban-client set manual-block unbanip 203.0.113.1
Hosts mit verwalteten authorized_keys
Manche Werkzeuge (Ansible, Keywarden, cloud-init, …) überschreiben ~/.ssh/authorized_keys.
Den Schlüssel dann in eine Datei legen, die sie nicht verwalten, und sicherstellen, dass sshd sie liest:
grep -i '^AuthorizedKeysFile' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
# z. B. AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
bash install.sh --key-file /tmp/webui.pub --from 198.51.100.10 \
--user root --authorized-keys-file /root/.ssh/authorized_keys2
Konfiguration – /etc/f2b-webctl.conf
# fail2ban-webui agent (f2b-webctl) – settings
# Jail used for manual bans from the web UI
MANUAL_JAIL=manual-block
# Addresses/networks that must never be banned (comma separated), e.g. your home IP.
# Private, loopback, link-local and CGNAT ranges are always protected.
PROTECTED=203.0.113.25,2001:db8:1234::/48
# Also protect all addresses of this host and the address of the web UI (yes/no)
PROTECT_OWN_ADDRESSES=yes
PROTECT_CLIENT=yes
Änderungen wirken sofort – der Agent liest die Datei bei jedem Aufruf.
Test auf dem Host
# direkt als root
f2b-webctl list | python3 -m json.tool | head -30
f2b-webctl ban 10.0.0.1 # → abgelehnt, geschützt
# derselbe Weg wie die Weboberfläche (Benutzer f2bweb über sudo)
runuser -u f2bweb -- env SSH_ORIGINAL_COMMAND=version sudo -n /usr/local/sbin/f2b-webctl
# was der Agent getan hat
journalctl -t f2b-webctl --since today # oder: grep f2b-webctl /var/log/auth.log
Aktualisieren
Den Installer der neuen Version mit denselben Optionen erneut ausführen. Konfiguration und Jail bleiben erhalten; Skript und Schlüsseleintrag werden ersetzt.
Deinstallieren
bash uninstall.sh --dry-run
bash uninstall.sh
| Option | Bedeutung |
|---|---|
--user NAME |
Agent-Benutzer (Standard f2bweb) |
--authorized-keys-file PFAD |
Datei mit dem Schlüsseleintrag |
--remove-user |
auch den Benutzer samt Home löschen |
--remove-jail |
auch das manuelle Jail löschen – hebt alle manuellen Sperren auf (sie werden vorher aufgelistet) |
--backup-dir VERZEICHNIS, --dry-run, --yes |
wie beim Installer |
Manuelle Installation
Wer es lieber von Hand macht – das sind alle Schritte des Installers:
install -o root -g root -m 0750 f2b-webctl /usr/local/sbin/f2b-webctl
nano /etc/f2b-webctl.conf # Inhalt siehe oben
useradd --system --create-home --home-dir /var/lib/f2bweb --shell /bin/sh f2bweb
usermod -p '*' f2bweb
visudo -f /etc/sudoers.d/f2b-webctl # Inhalt siehe "Was er tut", Schritt 4
install -d -o f2bweb -g f2bweb -m 700 /var/lib/f2bweb/.ssh
nano /var/lib/f2bweb/.ssh/authorized_keys # Zeile siehe Schritt 5
chown f2bweb: /var/lib/f2bweb/.ssh/authorized_keys
chmod 600 /var/lib/f2bweb/.ssh/authorized_keys
# manuelles Jail: die zwei Dateien aus "Das manuelle Jail", dann
touch /var/log/fail2ban-manual-block.log
fail2ban-client reload