# Konfiguration Die Weboberfläche wird über Umgebungsvariablen (`.env`, geladen per `env_file:`) und die Hostliste `config/hosts.yaml` konfiguriert. Eine vollständige, kommentierte Vorlage ist [`examples/.env.example`](../examples/.env.example). Änderungen brauchen `docker compose up -d` (das legt den Container neu an). Werte mit `$` (Passwort-Hashes, manche Secrets) müssen in der `.env` in **einfachen Anführungszeichen** stehen, sonst wertet Docker Compose sie als Variablen aus. ## Hosts – config/hosts.yaml ```yaml hosts: - name: web01 # shown in the UI: letters, digits, . _ - address: web01.example.org # DNS name or IP, reachable from the container port: 22 # optional, default 22 user: f2bweb # optional, default SSH_USER ``` Nach dem Hinzufügen eines Hosts `keyscan` erneut ausführen, dann neu starten: ```bash docker compose exec -it fail2ban-webui python -m webui keyscan docker compose exec fail2ban-webui python -m webui check docker compose restart ``` `F2B_HOSTS=name=adresse,name2=adresse2` (Port 22, Benutzer `SSH_USER`) wird aus Kompatibilitätsgründen weiter akzeptiert; Einträge aus beiden Quellen werden zusammengeführt. ## Allgemein | Variable | Standard | Bedeutung | |---|---|---| | `PUBLIC_URL` | – | externe URL, z. B. `https://fail2ban.example.org`. Pflicht für OIDC; mit `https://` bekommen Sitzungs-Cookies das `Secure`-Flag | | `DEFAULT_LANG` | `en` | Sprache, solange ein Benutzer im Dropdown keine gewählt hat (`en`, `de`, …) | | `TRUSTED_PROXY_HOPS` | `0` | Anzahl der Reverse Proxys, deren `X-Forwarded-For`/`-Proto`-Header vertraut wird. Hinter einem Proxy: `1`. Falsche Werte führen dazu, dass Protokoll und Login-Sperre die falsche Client-IP verwenden | | `SESSION_HOURS` | `12` | Gültigkeit einer Sitzung | | `SESSION_COOKIE_SECURE` | aus `PUBLIC_URL` | `Secure`-Flag des Cookies erzwingen oder abschalten | | `SECRET_KEY` | wird erzeugt | Schlüssel zum Signieren der Sitzungs-Cookies; standardmäßig einmalig in `data/secret_key` angelegt | | `TZ` | `Europe/Vienna` (Compose) | Zeitzone für Log- und Protokoll-Zeitstempel | | `CONFIG_FILE` | `/config/hosts.yaml` | Pfad der Hostliste im Container | | `DATA_DIR` | `/data` | Datenverzeichnis im Container | ## Anmeldung Die vollständige Einrichtung steht in [authentication.md](authentication.md). | Variable | Standard | Bedeutung | |---|---|---| | `AUTH_MODE` | `local` | `local`, `oidc`, `local,oidc` oder `proxy` | | `AUTH_USER` | `admin` | lokaler Benutzername | | `AUTH_PASSWORD_HASH` | – | scrypt-Hash aus `hash-password` (einfache Anführungszeichen!) | | `AUTH_PASSWORD_HASH_FILE` | – | Alternative: Datei mit dem Hash (z. B. ein Docker-Secret) | | `LOGIN_MAX_ATTEMPTS` | `5` | Fehlversuche pro Client-IP bis zur Sperre | | `LOGIN_LOCK_MINUTES` | `15` | Dauer des Sperrfensters | | `OIDC_ISSUER` | – | Issuer-URL; das Discovery-Dokument wird von `/.well-known/openid-configuration` gelesen | | `OIDC_DISCOVERY_URL` | – | vollständige Discovery-URL statt `OIDC_ISSUER` | | `OIDC_CLIENT_ID` / `OIDC_CLIENT_SECRET` | – | Client-Zugangsdaten | | `OIDC_SCOPES` | `openid email profile` | angeforderte Scopes | | `OIDC_USERNAME_CLAIM` | `preferred_username` | Claim, der als Benutzername angezeigt wird (Rückfall auf `email`, dann `sub`) | | `OIDC_GROUPS_CLAIM` | `groups` | Claim mit der Gruppenliste | | `OIDC_ALLOWED_GROUPS` | – | nur Mitglieder dieser Gruppen dürfen sich anmelden (durch Komma getrennt) | | `OIDC_ALLOWED_USERS` | – | nur diese Benutzernamen dürfen sich anmelden | | `OIDC_BUTTON_LABEL` | `SSO` | Text auf dem Anmeldeknopf („Anmelden mit …") | | `AUTH_PROXY_ALLOWED_IPS` | – | Proxy-Modus: nur Anfragen von diesen Adressen/Netzen annehmen | | `AUTH_PROXY_HEADER` | – | Proxy-Modus: Header mit dem Benutzernamen, z. B. `X-authentik-username` | | `AUTH_PROXY_LOGOUT_URL` | – | Proxy-Modus: Ziel des „Abmelden"-Knopfs | ## Agenten (SSH) | Variable | Standard | Bedeutung | |---|---|---| | `SSH_USER` | `f2bweb` | Standardbenutzer für Hosts ohne `user:` | | `SSH_KEY` | `/data/ssh/id_ed25519` | privater Schlüssel | | `KNOWN_HOSTS` | `/data/ssh/known_hosts` | festgelegte Host-Schlüssel (geschrieben von `keyscan`) | | `SSH_TIMEOUT` | `40` | Sekunden pro Agent-Aufruf | | `CACHE_SECONDS` | `15` | wie lange die Sperrliste zwischen zwei Seitenaufrufen zwischengespeichert wird | | `MANUAL_JAIL` | `manual-block` | Jail-Name im Hinweis der Oberfläche – das tatsächliche Jail bestimmt der Agent (`/etc/f2b-webctl.conf`) | | `AUDIT_LOG` | `/data/audit.log` | Protokoll (JSON-Zeilen) | Der SSH-Client ignoriert die System-`ssh_config`, verwendet nur den konfigurierten Schlüssel, stellt nie Rückfragen und lehnt unbekannte Host-Schlüssel ab. ## GeoIP | Variable | Standard | Bedeutung | |---|---|---| | `GEOIP_AUTO_DOWNLOAD` | `0` | `1`: die freie Städte-Datenbank [DB-IP Lite](https://db-ip.com/db/lite.php) (CC BY 4.0) herunterladen und monatlich erneuern | | `GEOIP_DB` | `/data/geoip/dbip-city-lite.mmdb` | Pfad der Datenbank – jede Städte-Datenbank im MaxMind-Format funktioniert (z. B. GeoLite2 City) | Mit einer Städte-Datenbank zeigt die Oberfläche auch die **Herkunftskarte** (Datenbanken nur mit Ländern haben keine Koordinaten). Die Karte ist Teil der App (Natural Earth, Public Domain) – es wird kein externer Kartendienst abgefragt. Ohne Datenbank bleibt die Spalte „Herkunft" leer und die Karte ausgeblendet. ## Loki und Grafana Mit Loki bekommt die Oberfläche pro IP einen **Verlauf**-Knopf mit den passenden Logzeilen der letzten Tage; mit Grafana bekommt jede Sperre einen Link nach Explore. | Variable | Standard | Bedeutung | |---|---|---| | `LOKI_URL` | – | z. B. `http://loki:3100`; leer = Verlauf ausgeschaltet | | `LOKI_SELECTOR` | `{job=~".+"}` | LogQL-Stream-Selektor für die Suche, z. B. `{job=~"fail2ban\|sshd\|nginx"}` | | `LOKI_DAYS` | `7` | wie weit zurück gesucht wird | | `LOKI_LIMIT` | `50` | maximale Anzahl Zeilen | | `LOKI_USER` / `LOKI_PASSWORD` | – | Basic Auth | | `LOKI_TENANT` | – | `X-Scope-OrgID` für mandantenfähiges Loki | | `GRAFANA_URL` | – | z. B. `https://grafana.example.org` | | `GRAFANA_DASHBOARD` | – | Pfad eines Dashboards für den Link in der Kopfzeile, z. B. `/d/abc123/security` | | `GRAFANA_LOKI_UID` | `loki` | UID der Loki-Datenquelle in Grafana (für Explore-Links) | Beispiel – das eigene Zugriffslog der Oberfläche von der Suche ausnehmen: ```ini LOKI_SELECTOR={job=~"fail2ban|ufw|nginx|sshd", domain!="fail2ban.example.org"} ``` ## Agent-Einstellungen Geschützte Adressen und das manuelle Jail werden **auf jedem Host** in `/etc/f2b-webctl.conf` eingestellt – siehe [agent.md](agent.md#konfiguration--etcf2b-webctlconf).