# Agent – f2b-webctl Auf jedem fail2ban-Host läuft der Agent [`f2b-webctl`](../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 ` | dauerhaft im manuellen Jail (`manual-block`) sperren | | `unban ` | in einem Jail entsperren | | `unban-all ` | 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 `PROTECTED` in `/etc/f2b-webctl.conf` steht (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). ```bash # 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: 1. sichert jede Datei, die er ändert, nach `--backup-dir` 2. installiert `/usr/local/sbin/f2b-webctl` (`root:root 0750`) 3. schreibt `/etc/f2b-webctl.conf` (bleibt erhalten, wenn sie schon existiert) 4. legt den Systembenutzer `f2bweb` an (Home `/var/lib/f2bweb`, ohne Passwort) und die sudo-Regel ``` Defaults!/usr/local/sbin/f2b-webctl env_keep += "SSH_ORIGINAL_COMMAND SSH_CLIENT" f2bweb ALL=(root) NOPASSWD: /usr/local/sbin/f2b-webctl ``` 5. 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 ``` 6. legt das Jail `manual-block` an, falls es noch nicht existiert (siehe unten) 7. 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](#hosts-mit-verwalteten-authorized_keys) | | `--manual-jail NAME` | `manual-block` | Jail für manuelle Sperren | | `--banaction AKTION` | aus `jail.local` | Banaction für ein neu angelegtes manuelles Jail | | `--docker` | – | Docker-Host: das neue manuelle Jail sperrt in `INPUT` **und** `DOCKER-USER` (iptables) – nicht mit `--banaction` kombinierbar | | `--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` ```ini # fail2ban-webui: never matches – the jail is only filled via # "fail2ban-client set manual-block banip " [Definition] failregex = ^FAIL2BAN-WEBUI-NEVER-MATCHES $ ignoreregex = ``` `/etc/fail2ban/jail.d/manual-block.local` ```ini # 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 den Agenten deshalb mit `--docker` installieren – das manuelle Jail sperrt dann in beiden Ketten: ```bash bash install.sh --key-file /tmp/webui.pub --from 198.51.100.10 --docker ``` Das erzeugt im Jail: ```ini action = iptables-allports[name=manual-block] iptables-allports[name=manual-block-docker, chain=DOCKER-USER] ``` Ein schon vorhandenes Jail ändert der Installer nicht; die zwei Zeilen dann von Hand in `/etc/fail2ban/jail.d/manual-block.local` eintragen und `fail2ban-client reload` ausführen. Nach der ersten Sperre prüfen: ```bash iptables -S DOCKER-USER | grep f2b ``` 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: ```bash 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: ```bash 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: ```bash 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 ```ini # 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 ```bash # 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 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: ```bash 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 ```