Initial version of fail2ban-webui

Web interface to view, ban and unban fail2ban IPs on several hosts via
SSH, generalised from the private f2b-web tool.

- Web UI (Flask/Waitress): hosts.yaml, local/OIDC/proxy authentication,
  English/German UI, origin map, optional Loki/Grafana/GeoIP, CLI helpers
- Agent f2b-webctl with install.sh/uninstall.sh (dedicated user + sudo,
  from= restriction, protected networks, manual jail)
- Hardened Docker image, examples, documentation, smoke test, testbed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
schiwagoaandClaude Opus 5.5 committed 2026-10-25 15:38:17 +01:00
commit 2e3f79236c
44 files changed
+4280

No files matched your search

+101
View File
@@ -0,0 +1,101 @@
{
"_name": "Deutsch",
"title": "Fail2ban-Steuerung",
"language": "Sprache",
"refresh": "Aktualisieren",
"grafana": "Grafana",
"logout": "Abmelden",
"signed_in_as": "Angemeldet als {user}",
"generated": "Stand: {ts}",
"ban_heading": "IP sperren",
"ban_ip_placeholder": "IP-Adresse, z. B. 203.0.113.7",
"ban_note_placeholder": "Notiz (optional, nur fürs Protokoll)",
"ban_button": "Dauerhaft sperren",
"ban_hint": "Die Sperre landet im Jail {jail} (dauerhaft). Private Netze und auf dem Host geschützte Adressen lehnt der Agent ab.",
"bans_heading": "Aktuelle Sperren",
"filter_search": "Suchen (IP, Land, Stadt)",
"filter_all_hosts": "Alle Hosts",
"filter_all_jails": "Alle Jails",
"col_host": "Host",
"col_jail": "Jail",
"col_ip": "IP",
"col_origin": "Herkunft",
"col_since": "Gesperrt seit",
"col_until": "Bis",
"col_actions": "Aktionen",
"loading": "Lade …",
"no_bans": "Keine Sperren gefunden.",
"more_rows": "… {n} weitere – Filter verwenden.",
"permanent": "dauerhaft",
"btn_unban": "Entsperren",
"btn_unban_everywhere": "Überall",
"btn_history": "Verlauf",
"jail": "Jail",
"jail_current": "aktuell",
"jail_total": "seit Start",
"audit_heading": "Protokoll (letzte 50 Aktionen)",
"audit_empty": "Noch keine Aktionen.",
"audit_banned": "gesperrt",
"audit_unbanned": "entsperrt",
"audit_line": "{ts} – {ip} {what} auf {hosts}",
"audit_where_jail": " (Jail {jail})",
"audit_where_all": " (alle Jails)",
"audit_failed": " – FEHLER",
"audit_by": " · von {user} ({client})",
"history_title": "Verlauf {ip} ({days} Tage)",
"history_close": "Schließen",
"origin_unknown": "Herkunft unbekannt",
"history_none": "Keine Einträge in Loki.",
"confirm_unban_all": "{ip} auf ALLEN Hosts in ALLEN Jails entsperren?",
"confirm_unban": "{ip} auf {host} im Jail {jail} entsperren?",
"confirm_ban": "{ip} auf {hosts} DAUERHAFT sperren?",
"toast_unban": "Entsperren {ip}: {result}",
"toast_ban": "Sperren {ip}: {result}",
"toast_load_failed": "Laden fehlgeschlagen: {error}",
"select_host": "Bitte mindestens einen Host wählen.",
"result_ok": "OK",
"result_error": "Fehler",
"footer_geo": "IP-Geolokalisierung:",
"login_title": "Anmelden",
"login_user": "Benutzername",
"login_password": "Passwort",
"login_button": "Anmelden",
"login_oidc": "Anmelden mit {provider}",
"login_or": "oder",
"login_failed": "Benutzername oder Passwort falsch.",
"login_locked": "Zu viele Fehlversuche. Bitte in {minutes} Minuten erneut versuchen.",
"login_oidc_failed": "Single Sign-on fehlgeschlagen: {error}",
"login_denied": "Das Konto {user} darf diese Anwendung nicht verwenden.",
"login_csrf": "Sitzung abgelaufen – bitte erneut versuchen.",
"error_title": "Fehler {code}",
"error_back": "Zurück zur Startseite",
"err_login_required": "Nicht angemeldet oder Sitzung abgelaufen – bitte Seite neu laden.",
"err_csrf": "CSRF-Token fehlt oder ist ungültig – Seite neu laden.",
"err_origin": "Anfrage fremder Herkunft (Origin) abgelehnt.",
"err_json": "JSON erwartet.",
"err_invalid_ip": "Ungültige IP-Adresse: {value}",
"err_no_host": "Kein gültiger Host ausgewählt.",
"err_unknown_host": "Unbekannter Host.",
"err_invalid_jail": "Ungültiger Jail-Name.",
"err_timeout": "Zeitüberschreitung bei {host}",
"err_ssh": "{host}: {detail}",
"err_exit": "{host}: Exit-Code {code}",
"err_loki_disabled": "Loki ist nicht konfiguriert.",
"err_loki_http": "Loki-Fehler {code}: {detail}",
"err_loki_timeout": "Loki-Abfrage dauerte zu lange (Timeout).",
"err_loki_unreachable": "Loki nicht erreichbar: {error}",
"err_forbidden_proxy": "Zugriff nur über den konfigurierten Reverse Proxy erlaubt.",
"agent_f2b_down": "fail2ban ist auf dem Host nicht erreichbar: {detail}",
"agent_invalid_ip": "Ungültige IP-Adresse: {value}",
"agent_protected": "{ip} ist auf diesem Host geschützt (privates Netz, eigene Adresse oder PROTECTED-Liste).",
"agent_no_manual_jail": "Das Jail {jail} gibt es auf diesem Host nicht.",
"agent_unknown_jail": "Unbekanntes Jail: {jail}",
"agent_not_root": "Der Agent läuft nicht als root – sudo-Regel prüfen.",
"agent_not_allowed": "Der Agent hat den Befehl abgelehnt.",
"map_heading": "Herkunftskarte",
"map_summary": "{ips} Sperren aus {places} Orten",
"map_unknown": " · {n} ohne Standort",
"map_hint": "Punkt anklicken, um die Liste zu filtern.",
"map_point": "{place}: {n} Sperren",
"map_reset": "Alle anzeigen"
}
+101
View File
@@ -0,0 +1,101 @@
{
"_name": "English",
"title": "Fail2ban Web UI",
"language": "Language",
"refresh": "Refresh",
"grafana": "Grafana",
"logout": "Sign out",
"signed_in_as": "Signed in as {user}",
"generated": "As of: {ts}",
"ban_heading": "Ban IP address",
"ban_ip_placeholder": "IP address, e.g. 203.0.113.7",
"ban_note_placeholder": "Note (optional, audit log only)",
"ban_button": "Ban permanently",
"ban_hint": "The ban goes into the jail {jail} (permanent). Private networks and addresses protected on the host are rejected by the agent.",
"bans_heading": "Current bans",
"filter_search": "Search (IP, country, city)",
"filter_all_hosts": "All hosts",
"filter_all_jails": "All jails",
"col_host": "Host",
"col_jail": "Jail",
"col_ip": "IP",
"col_origin": "Origin",
"col_since": "Banned since",
"col_until": "Until",
"col_actions": "Actions",
"loading": "Loading …",
"no_bans": "No bans found.",
"more_rows": "… {n} more – use the filters.",
"permanent": "permanent",
"btn_unban": "Unban",
"btn_unban_everywhere": "Everywhere",
"btn_history": "History",
"jail": "Jail",
"jail_current": "current",
"jail_total": "since start",
"audit_heading": "Audit log (last 50 actions)",
"audit_empty": "No actions yet.",
"audit_banned": "banned",
"audit_unbanned": "unbanned",
"audit_line": "{ts} – {ip} {what} on {hosts}",
"audit_where_jail": " (jail {jail})",
"audit_where_all": " (all jails)",
"audit_failed": " – FAILED",
"audit_by": " · by {user} ({client})",
"history_title": "History {ip} ({days} days)",
"history_close": "Close",
"origin_unknown": "Origin unknown",
"history_none": "No entries in Loki.",
"confirm_unban_all": "Unban {ip} on ALL hosts in ALL jails?",
"confirm_unban": "Unban {ip} on {host} in jail {jail}?",
"confirm_ban": "Ban {ip} PERMANENTLY on {hosts}?",
"toast_unban": "Unban {ip}: {result}",
"toast_ban": "Ban {ip}: {result}",
"toast_load_failed": "Loading failed: {error}",
"select_host": "Please select at least one host.",
"result_ok": "OK",
"result_error": "Error",
"footer_geo": "IP geolocation:",
"login_title": "Sign in",
"login_user": "Username",
"login_password": "Password",
"login_button": "Sign in",
"login_oidc": "Sign in with {provider}",
"login_or": "or",
"login_failed": "Invalid username or password.",
"login_locked": "Too many failed attempts. Try again in {minutes} minutes.",
"login_oidc_failed": "Single sign-on failed: {error}",
"login_denied": "The account {user} is not allowed to use this application.",
"login_csrf": "Session expired – please try again.",
"error_title": "Error {code}",
"error_back": "Back to the start page",
"err_login_required": "Not signed in or session expired – please reload the page.",
"err_csrf": "CSRF token missing or invalid – reload the page.",
"err_origin": "Request from a foreign origin rejected.",
"err_json": "JSON expected.",
"err_invalid_ip": "Invalid IP address: {value}",
"err_no_host": "No valid host selected.",
"err_unknown_host": "Unknown host.",
"err_invalid_jail": "Invalid jail name.",
"err_timeout": "Timeout talking to {host}",
"err_ssh": "{host}: {detail}",
"err_exit": "{host}: exit code {code}",
"err_loki_disabled": "Loki is not configured.",
"err_loki_http": "Loki error {code}: {detail}",
"err_loki_timeout": "Loki query took too long (timeout).",
"err_loki_unreachable": "Loki not reachable: {error}",
"err_forbidden_proxy": "Access is only allowed via the configured reverse proxy.",
"agent_f2b_down": "fail2ban is not reachable on the host: {detail}",
"agent_invalid_ip": "Invalid IP address: {value}",
"agent_protected": "{ip} is protected on this host (private network, own address or PROTECTED list).",
"agent_no_manual_jail": "The jail {jail} does not exist on this host.",
"agent_unknown_jail": "Unknown jail: {jail}",
"agent_not_root": "The agent does not run as root – check the sudo rule.",
"agent_not_allowed": "The agent rejected the command.",
"map_heading": "Origin map",
"map_summary": "{ips} bans from {places} places",
"map_unknown": " · {n} without location",
"map_hint": "Click a point to filter the list.",
"map_point": "{place}: {n} bans",
"map_reset": "Show all"
}