Docs: translate README and guides to German
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>
This commit is contained in:
1 parent
2e3f79236c
commit
019c74a418
8 files changed
+469
-463
No files matched your search
+62
-61
@@ -1,32 +1,32 @@
|
||||
# Operations
|
||||
# Betrieb
|
||||
|
||||
All commands are run in the directory with `docker-compose.yaml` (e.g. `/opt/fail2ban-webui`).
|
||||
Alle Befehle im Verzeichnis mit der `docker-compose.yaml` ausführen (z. B. `/opt/fail2ban-webui`).
|
||||
|
||||
## Status and logs
|
||||
## Status und Logs
|
||||
|
||||
```bash
|
||||
docker compose ps # Up … (healthy)
|
||||
docker compose logs --tail 100 fail2ban-webui
|
||||
docker compose logs -f fail2ban-webui | grep -E 'AUDIT|LOGIN|ERROR|WARNING'
|
||||
docker compose run --rm fail2ban-webui check # every agent reachable?
|
||||
docker compose run --rm fail2ban-webui check # jeder Agent erreichbar?
|
||||
```
|
||||
|
||||
Log lines of interest:
|
||||
Wichtige Logzeilen:
|
||||
|
||||
| Line | Meaning |
|
||||
| Zeile | Bedeutung |
|
||||
|---|---|
|
||||
| `fail2ban-webui 1.0.0 – hosts: … – auth: … – loki: … – geoip: …` | start summary |
|
||||
| `AUDIT {…}` | ban/unban with user, client IP, hosts and result |
|
||||
| `LOGIN_OK` / `LOGIN_FAILED` / `LOGIN_LOCKED` / `LOGOUT` | sign-in events |
|
||||
| `OIDC_FAILED` / `OIDC_DENIED` | SSO errors / account not allowed |
|
||||
| `fail2ban-webui 1.0.0 – hosts: … – auth: … – loki: … – geoip: …` | Zusammenfassung beim Start |
|
||||
| `AUDIT {…}` | Sperren/Entsperren mit Benutzer, Client-IP, Hosts und Ergebnis |
|
||||
| `LOGIN_OK` / `LOGIN_FAILED` / `LOGIN_LOCKED` / `LOGOUT` | Anmeldeereignisse |
|
||||
| `OIDC_FAILED` / `OIDC_DENIED` | SSO-Fehler / Konto nicht zugelassen |
|
||||
|
||||
The audit log is also kept in `data/audit.log` (one JSON object per line):
|
||||
Das Protokoll liegt zusätzlich in `data/audit.log` (ein JSON-Objekt pro Zeile):
|
||||
|
||||
```bash
|
||||
tail -n 20 data/audit.log | python3 -m json.tool --json-lines
|
||||
```
|
||||
|
||||
On the hosts every agent action is in syslog:
|
||||
Auf den Hosts steht jede Agent-Aktion im Syslog:
|
||||
|
||||
```bash
|
||||
journalctl -t f2b-webctl --since today
|
||||
@@ -35,63 +35,64 @@ journalctl -t f2b-webctl --since today
|
||||
## Update
|
||||
|
||||
```bash
|
||||
cp -a .env docker-compose.yaml config /backups/fail2ban-webui_$(date +%F)/ # or your backup location
|
||||
cp -a .env docker-compose.yaml config /backups/fail2ban-webui_$(date +%F)/ # oder dein Backup-Ort
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker compose ps
|
||||
docker compose run --rm fail2ban-webui check
|
||||
```
|
||||
|
||||
Read the [changelog](../CHANGELOG.md) first – if it mentions a new agent version, update
|
||||
the agents as well (re-run `install.sh` with the same options, see [agent.md](agent.md#update)).
|
||||
The `1` tag only moves within the 1.x series; breaking changes get a new major version.
|
||||
Vorher das [Changelog](../CHANGELOG.md) lesen – nennt es eine neue Agent-Version, auch die
|
||||
Agenten aktualisieren (`install.sh` mit denselben Optionen erneut ausführen, siehe
|
||||
[agent.md](agent.md#aktualisieren)). Der Tag `1` bewegt sich nur innerhalb von 1.x;
|
||||
inkompatible Änderungen bekommen eine neue Hauptversion.
|
||||
|
||||
Rebuild/pull regularly even without new features: the image is rebuilt with current
|
||||
Debian security updates.
|
||||
Auch ohne neue Funktionen regelmäßig neu ziehen bzw. bauen: Das Image wird mit aktuellen
|
||||
Debian-Sicherheitsupdates neu gebaut.
|
||||
|
||||
## Backup
|
||||
|
||||
| What | Why |
|
||||
| Was | Warum |
|
||||
|---|---|
|
||||
| `.env` | settings, password hash, OIDC secret |
|
||||
| `config/hosts.yaml` | host list |
|
||||
| `data/ssh/` | private key and pinned host keys – without them every agent needs the new key |
|
||||
| `data/audit.log` | audit trail |
|
||||
| `data/secret_key` | only keeps sessions valid; losing it signs everybody out |
|
||||
| `.env` | Einstellungen, Passwort-Hash, OIDC-Secret |
|
||||
| `config/hosts.yaml` | Hostliste |
|
||||
| `data/ssh/` | privater Schlüssel und festgelegte Host-Schlüssel – ohne sie braucht jeder Agent den neuen Schlüssel |
|
||||
| `data/audit.log` | Protokoll |
|
||||
| `data/secret_key` | hält nur Sitzungen gültig; geht er verloren, werden alle abgemeldet |
|
||||
|
||||
`data/geoip/` is downloaded again automatically.
|
||||
`data/geoip/` wird automatisch neu heruntergeladen.
|
||||
|
||||
```bash
|
||||
tar -cpzf /backups/fail2ban-webui_$(date +%F_%H-%M).tar.gz .env docker-compose.yaml config data
|
||||
sha256sum /backups/fail2ban-webui_*.tar.gz | tail -n1
|
||||
```
|
||||
|
||||
The archive contains the private SSH key – store it accordingly.
|
||||
Das Archiv enthält den privaten SSH-Schlüssel – entsprechend sicher aufbewahren.
|
||||
|
||||
## Moving to another host
|
||||
## Umzug auf einen anderen Host
|
||||
|
||||
1. `docker compose stop` on the old host, create the archive as above.
|
||||
2. Copy it, unpack with `tar -xpzf` (keeps owner 10050 and permissions).
|
||||
3. On **every agent** add the new address to `from=` – easiest by re-running
|
||||
`install.sh … --from <new address>`.
|
||||
4. `docker compose up -d`, then `check`.
|
||||
1. Auf dem alten Host `docker compose stop`, Archiv wie oben erstellen.
|
||||
2. Kopieren, mit `tar -xpzf` entpacken (behält Besitzer 10050 und Rechte).
|
||||
3. Auf **jedem Agenten** die neue Adresse in `from=` aufnehmen – am einfachsten
|
||||
`install.sh … --from <neue Adresse>` erneut ausführen.
|
||||
4. `docker compose up -d`, danach `check`.
|
||||
|
||||
## Rotating the SSH key
|
||||
## SSH-Schlüssel tauschen
|
||||
|
||||
```bash
|
||||
docker compose run --rm fail2ban-webui keygen --force
|
||||
# on every host:
|
||||
bash install.sh --key-file new.pub --from … (same options as before)
|
||||
# auf jedem Host:
|
||||
bash install.sh --key-file new.pub --from … (dieselben Optionen wie zuvor)
|
||||
```
|
||||
|
||||
The installer replaces only entries with the same key; remove the old one with
|
||||
`uninstall.sh` first or delete its line from `authorized_keys` (it contains
|
||||
Der Installer ersetzt nur Einträge mit demselben Schlüssel; den alten vorher mit
|
||||
`uninstall.sh` entfernen oder seine Zeile aus `authorized_keys` löschen (sie enthält
|
||||
`command="…f2b-webctl"`).
|
||||
|
||||
## Protecting the login with fail2ban
|
||||
## Login mit fail2ban absichern
|
||||
|
||||
The UI locks a client after 5 failed logins itself. To ban persistent attackers on the
|
||||
firewall, let fail2ban on the **proxy host** read the container log.
|
||||
Die Oberfläche sperrt einen Client nach 5 Fehlversuchen selbst. Um hartnäckige Angreifer an
|
||||
der Firewall zu sperren, liest fail2ban auf dem **Proxy-Host** das Container-Log.
|
||||
|
||||
`/etc/fail2ban/filter.d/fail2ban-webui.conf`
|
||||
|
||||
@@ -124,27 +125,27 @@ fail2ban-client reload
|
||||
fail2ban-regex /var/lib/docker/containers/*/*-json.log /etc/fail2ban/filter.d/fail2ban-webui.conf
|
||||
```
|
||||
|
||||
This only works when the container sees the real client address (`TRUSTED_PROXY_HOPS`
|
||||
set correctly). User names are logged with spaces and control characters replaced, so a
|
||||
crafted user name cannot inject a second log line.
|
||||
Das funktioniert nur, wenn der Container die echte Client-Adresse sieht (`TRUSTED_PROXY_HOPS`
|
||||
richtig gesetzt). Benutzernamen werden mit ersetzten Leer- und Steuerzeichen protokolliert;
|
||||
ein präparierter Benutzername kann also keine zweite Logzeile einschleusen.
|
||||
|
||||
## Troubleshooting
|
||||
## Fehlersuche
|
||||
|
||||
| Symptom | Cause / fix |
|
||||
| Symptom | Ursache / Lösung |
|
||||
|---|---|
|
||||
| Container exits: `… is not writable for UID 10050` | `chown -R 10050:10050 data` |
|
||||
| Container exits: `AUTH_MODE=local needs AUTH_PASSWORD_HASH` | run `hash-password`, paste the line with single quotes |
|
||||
| Container exits: `No hosts configured` | `config/hosts.yaml` missing or empty; on Windows/Docker Desktop: the drive cannot be bind-mounted |
|
||||
| Login always fails after pasting the hash | single quotes missing in `.env` – Compose ate the `$` parts |
|
||||
| Everybody locked out together / audit shows the proxy IP | `TRUSTED_PROXY_HOPS` not set |
|
||||
| `Host key verification failed` | host not in `known_hosts` or its key changed → `keyscan`, compare fingerprints |
|
||||
| `Permission denied (publickey)` | key not installed for that user, wrong `user:` in `hosts.yaml`, wrong `from=` (the address the host sees!), or sshd does not read that `authorized_keys` file |
|
||||
| `sudo: a password is required` | sudo rule missing → re-run `install.sh` |
|
||||
| `The agent does not run as root` | forced command without `sudo -n` for a non-root user → re-run `install.sh` |
|
||||
| `Timeout talking to …` | firewall/port, or the host is slow – raise `SSH_TIMEOUT` |
|
||||
| `The jail manual-block does not exist on this host` | installed with `--no-jail` or with another `--manual-jail`; check `MANUAL_JAIL` in `/etc/f2b-webctl.conf` |
|
||||
| Bans have no start/end time | fail2ban older than 0.11 (no `--with-time`) |
|
||||
| Banned IP still reaches a Docker service | banaction blocks only `INPUT` – see [Docker hosts](agent.md#docker-hosts) |
|
||||
| OIDC: `redirect_uri` mismatch | provider must allow exactly `<PUBLIC_URL>/auth/callback` |
|
||||
| OIDC: `mismatching_state` | session cookie lost between redirect and callback: `PUBLIC_URL` host differs from the one in the browser, or `https` without `Secure`/proxy headers |
|
||||
| OIDC: "account … is not allowed" | user not in `OIDC_ALLOWED_GROUPS`; check that the provider sends the `groups` claim |
|
||||
| Container beendet sich: `… is not writable for UID 10050` | `chown -R 10050:10050 data` |
|
||||
| Container beendet sich: `AUTH_MODE=local needs AUTH_PASSWORD_HASH` | `hash-password` ausführen, Zeile mit einfachen Anführungszeichen einfügen |
|
||||
| Container beendet sich: `No hosts configured` | `config/hosts.yaml` fehlt oder ist leer; unter Windows/Docker Desktop: das Laufwerk lässt sich nicht einbinden |
|
||||
| Anmeldung scheitert immer, nachdem der Hash eingefügt wurde | einfache Anführungszeichen in der `.env` fehlen – Compose hat die `$`-Teile verschluckt |
|
||||
| Alle werden gemeinsam gesperrt / Protokoll zeigt die Proxy-IP | `TRUSTED_PROXY_HOPS` nicht gesetzt |
|
||||
| `Host key verification failed` | Host nicht in `known_hosts` oder sein Schlüssel hat sich geändert → `keyscan`, Fingerprints vergleichen |
|
||||
| `Permission denied (publickey)` | Schlüssel für diesen Benutzer nicht installiert, falsches `user:` in `hosts.yaml`, falsches `from=` (die Adresse, die der Host sieht!) oder sshd liest diese `authorized_keys`-Datei nicht |
|
||||
| `sudo: a password is required` | sudo-Regel fehlt → `install.sh` erneut ausführen |
|
||||
| `The agent does not run as root` | Forced-Command ohne `sudo -n` für einen Nicht-root-Benutzer → `install.sh` erneut ausführen |
|
||||
| `Timeout talking to …` | Firewall/Port, oder der Host ist langsam – `SSH_TIMEOUT` erhöhen |
|
||||
| `The jail manual-block does not exist on this host` | mit `--no-jail` oder einem anderen `--manual-jail` installiert; `MANUAL_JAIL` in `/etc/f2b-webctl.conf` prüfen |
|
||||
| Sperren haben keine Start-/Endzeit | fail2ban älter als 0.11 (kein `--with-time`) |
|
||||
| Gesperrte IP erreicht trotzdem einen Docker-Dienst | Banaction sperrt nur `INPUT` – siehe [Docker-Hosts](agent.md#docker-hosts) |
|
||||
| OIDC: `redirect_uri` passt nicht | Provider muss genau `<PUBLIC_URL>/auth/callback` erlauben |
|
||||
| OIDC: `mismatching_state` | Sitzungs-Cookie zwischen Weiterleitung und Callback verloren: Host in `PUBLIC_URL` weicht vom Browser ab, oder `https` ohne `Secure`/Proxy-Header |
|
||||
| OIDC: „Konto … darf diese Anwendung nicht verwenden" | Benutzer nicht in `OIDC_ALLOWED_GROUPS`; prüfen, ob der Provider den Claim `groups` mitschickt |
|
||||
Reference in new issue
Block a user