Docs: tested single-host install, NPM integration, installer --docker

- README: step-by-step installation of web UI and agent on one host,
  exactly as tested (agent after keygen, all "run" helpers before
  "up -d", http PUBLIC_URL and TRUSTED_PROXY_HOPS=0 without a proxy)
- README: attach to an existing Nginx Proxy Manager in Docker – shared
  network via docker-compose.override.yaml, no published port,
  gw_priority so SSH to the agent keeps the source address of the own
  network (otherwise from= rejects it), TLS settings, test
- install.sh --docker: the new manual jail bans in INPUT and DOCKER-USER
- Running container: helpers via "docker compose exec … python -m webui"
  (run fails with "Address already in use"); troubleshooting entries

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
schiwagoaandClaude Opus 5.5 committed 2026-10-25 19:50:33 +01:00
1 parent d03aa6f0d2
commit b36499bbf5
8 files changed
+303 -26

No files matched your search

+253 -15
View File
@@ -74,40 +74,278 @@ danach den Container neu starten).
### fail2ban-Hosts (Agent)
- fail2ban ≥ 0.11 (Start-/Endzeiten der Sperren brauchen `--with-time`)
- `sudo` für den Standardbenutzer `f2bweb`; mit einem root-Schlüssel nicht nötig
- `bash`, `ssh-keygen` (Teil von OpenSSH) für den Installer
## Installation auf einem Host
Weboberfläche und Agent auf demselben Docker-Host – so getestet auf Ubuntu 26.04 (LXC).
Weitere fail2ban-Hosts kommen später nur mit dem Agenten dazu ([docs/agent.md](docs/agent.md)).
Im Beispiel hat der Host die LAN-Adresse `192.168.1.10` – überall durch deine ersetzen.
### fail2ban vorbereiten
```bash
apt install -y fail2ban python3 sudo openssh-server
```
```bash
systemctl enable --now fail2ban
```
```bash
fail2ban-client ping # Server replied: pong
```
- fail2ban ≥ 0.11 (Start-/Endzeiten der Sperren brauchen `--with-time`)
- `sudo` nur für den Standardbenutzer `f2bweb`; mit einem root-Schlüssel nicht nötig
- `bash`, `ssh-keygen` (Teil von OpenSSH) für den Installer
### Quellen holen
## Schnellstart
```bash
git clone https://git.retronerd.at/schiwagoa/fail2ban-webui.git /opt/fail2ban-webui-src
```
Voraussetzungen siehe oben (Grundpakete, Docker, Agent auf den fail2ban-Hosts).
### Weboberfläche einrichten
```bash
mkdir -p /opt/fail2ban-webui/{config,data} && cd /opt/fail2ban-webui
curl -fsSLo docker-compose.yaml https://git.retronerd.at/schiwagoa/fail2ban-webui/raw/branch/main/examples/docker-compose.yaml
curl -fsSLo .env https://git.retronerd.at/schiwagoa/fail2ban-webui/raw/branch/main/examples/.env.example
curl -fsSLo config/hosts.yaml https://git.retronerd.at/schiwagoa/fail2ban-webui/raw/branch/main/examples/hosts.yaml.example
chown -R 10050:10050 data
```
```bash
docker compose run --rm -it fail2ban-webui hash-password # Zeile in die .env übernehmen
nano .env # PUBLIC_URL, Hash, DEFAULT_LANG=de …
docker compose run --rm fail2ban-webui keygen # öffentlicher Schlüssel für die Agenten
# auf jedem fail2ban-Host den Agenten installieren (docs/agent.md), danach:
nano config/hosts.yaml # Beispiel-Hosts durch deine ersetzen!
curl -fsSLo docker-compose.yaml https://git.retronerd.at/schiwagoa/fail2ban-webui/raw/branch/main/examples/docker-compose.yaml
```
```bash
curl -fsSLo .env https://git.retronerd.at/schiwagoa/fail2ban-webui/raw/branch/main/examples/.env.example
```
Der Container läuft als UID 10050 und muss in `data/` schreiben:
```bash
chown -R 10050:10050 data && chmod 700 data
```
Für den Zugriff direkt im LAN (ohne Reverse Proxy) den Port an die LAN-Adresse binden –
hinter einem Nginx Proxy Manager diesen Schritt [weglassen](#hinter-einem-vorhandenen-nginx-proxy-manager-docker):
```bash
sed -i 's/"127.0.0.1:8080:8080"/"192.168.1.10:8080:8080"/' docker-compose.yaml
```
Adresse, Sprache und Proxy-Einstellung setzen. Ohne TLS muss `PUBLIC_URL` mit `http://`
beginnen, sonst schickt der Browser das Sitzungs-Cookie nicht mit; ohne Proxy gehört
`TRUSTED_PROXY_HOPS` auf `0`:
```bash
sed -i -e 's|^PUBLIC_URL=.*|PUBLIC_URL=http://192.168.1.10:8080|' -e 's|^DEFAULT_LANG=.*|DEFAULT_LANG=de|' -e 's|^TRUSTED_PROXY_HOPS=.*|TRUSTED_PROXY_HOPS=0|' .env
```
Passwort-Hash erzeugen (mindestens 12 Zeichen, zweimal eingeben):
```bash
docker compose run --rm -it fail2ban-webui hash-password
```
Die ausgegebene Zeile `AUTH_PASSWORD_HASH='scrypt:…'` kopieren und in der `.env` die Zeile
`AUTH_PASSWORD_HASH='scrypt:...'` damit ersetzen – die einfachen Anführungszeichen bleiben:
```bash
nano .env
```
SSH-Schlüssel der Weboberfläche erzeugen:
```bash
docker compose run --rm fail2ban-webui keygen
```
### Agent installieren
Probelauf – zeigt nur, was passieren würde. `172.23.51.10` ist die feste Adresse der
Weboberfläche in ihrem Docker-Netz:
```bash
bash /opt/fail2ban-webui-src/agent/install.sh --key-file /opt/fail2ban-webui/data/ssh/id_ed25519.pub --from 172.23.51.10 --dry-run
```
Installieren und mit `y` bestätigen – am Ende meldet der Selbsttest
`2 jails, 0 bans: manual-block, sshd`. Laufen auf dem Host weitere Docker-Dienste mit
veröffentlichten Ports (z. B. ein Nginx Proxy Manager), zusätzlich `--docker` anhängen,
damit manuelle Sperren auch dort greifen:
```bash
bash /opt/fail2ban-webui-src/agent/install.sh --key-file /opt/fail2ban-webui/data/ssh/id_ed25519.pub --from 172.23.51.10
```
### Host eintragen und testen
```bash
cat > config/hosts.yaml <<'EOF'
hosts:
- name: srv200
address: host.docker.internal
EOF
```
Host-Schlüssel holen – die Fingerprints werden angezeigt, mit `y` bestätigen:
```bash
docker compose run --rm -it fail2ban-webui keyscan
```
Verbindung testen – erwartet: `OK srv200 agent 1.0.0, 2 jails, 0 bans`:
```bash
docker compose run --rm fail2ban-webui check
```
### Starten
```bash
docker compose up -d
```
Die Oberfläche lauscht auf `127.0.0.1:8080` – davor gehört ein Reverse Proxy mit TLS.
```bash
docker compose ps # Up … (healthy) nach etwa 30 Sekunden
```
```bash
docker compose logs fail2ban-webui # hosts: srv200 – auth: local – geoip: on, danach "GeoIP database updated"
```
Im Browser `http://192.168.1.10:8080` öffnen und mit `admin` und dem Passwort von oben anmelden.
> `docker compose run` funktioniert nur, solange der Dienst **nicht** läuft – die feste
> IP-Adresse wäre sonst doppelt vergeben (`Address already in use`). Im laufenden Betrieb
> die Hilfsbefehle mit `exec` aufrufen, z. B. `docker compose exec fail2ban-webui python -m webui check`.
## Hinter einem vorhandenen Nginx Proxy Manager (Docker)
Ausgangslage: Nginx Proxy Manager (NPM) läuft auf demselben Host als Docker-Container,
fail2ban ist auf dem Host installiert. Die Weboberfläche bekommt dann **keinen**
veröffentlichten Port, sondern hängt zusätzlich im Docker-Netz von NPM; erreichbar ist sie
nur über NPM mit TLS.
Voraussetzung: Docker Engine ≥ 28 und Compose ≥ 2.33 (für `gw_priority`, siehe Schritt 3).
### 1. Manuelle Sperren auch für Docker-Ports
Verkehr zu veröffentlichten Docker-Ports – also auch zu NPM – läuft nicht über die Kette
`INPUT`, sondern über `DOCKER-USER`. Den Agenten deshalb mit `--docker` installieren:
```bash
bash /opt/fail2ban-webui-src/agent/install.sh --key-file /opt/fail2ban-webui/data/ssh/id_ed25519.pub --from 172.23.51.10 --docker
```
War der Agent schon ohne `--docker` installiert, lässt der Installer das vorhandene Jail
unverändert. Dann die Datei sichern, die zwei `action`-Zeilen ergänzen und fail2ban neu laden:
```bash
mkdir -p /backups/config_backups && cp -a /etc/fail2ban/jail.d/manual-block.local /backups/config_backups/manual-block.local_$(date +%F_%H-%M)
```
```bash
nano /etc/fail2ban/jail.d/manual-block.local
```
```ini
action = iptables-allports[name=manual-block]
iptables-allports[name=manual-block-docker, chain=DOCKER-USER]
```
```bash
fail2ban-client reload && fail2ban-client status manual-block
```
### 2. Docker-Netz von NPM ermitteln
```bash
docker ps --format '{{.Names}} {{.Image}}' | grep -iE 'npm|proxy-manager'
```
```bash
docker inspect <NPM-Container> --format '{{range $n, $c := .NetworkSettings.Networks}}{{$n}}{{"\n"}}{{end}}'
```
### 3. Weboberfläche ins NPM-Netz hängen
Den veröffentlichten Port entfernen – erreichbar ist die Oberfläche danach nur noch über NPM:
```bash
cd /opt/fail2ban-webui && sed -i '/^ ports:$/,/8080:8080"$/d' docker-compose.yaml
```
Das NPM-Netz kommt in eine eigene Datei `docker-compose.override.yaml`, die Docker Compose
automatisch dazulädt. Den Netznamen aus Schritt 2 in `NPM_NET` setzen:
```bash
NPM_NET=npm_default
```
```bash
cat > docker-compose.override.yaml <<EOF
# fail2ban-webui hinter Nginx Proxy Manager: zusätzlich im Netz von NPM.
# gw_priority hält die Standardroute im eigenen Netz – sonst kommt die
# SSH-Verbindung zum Agenten mit der Adresse aus dem NPM-Netz an und
# --from 172.23.51.10 lehnt sie ab.
services:
fail2ban-webui:
networks:
fail2ban-webui.dockernetwork.local:
gw_priority: 1
npm: {}
networks:
npm:
name: ${NPM_NET}
external: true
EOF
```
```bash
docker compose config --quiet && echo "Konfiguration ok"
```
### 4. Adresse und Proxy-Einstellung
```bash
sed -i -e 's|^PUBLIC_URL=.*|PUBLIC_URL=https://fail2ban.example.org|' -e 's|^TRUSTED_PROXY_HOPS=.*|TRUSTED_PROXY_HOPS=1|' .env
```
### 5. Neu starten und prüfen
```bash
docker compose up -d
```
```bash
docker compose exec fail2ban-webui python -m webui check
```
### 6. DNS und Proxy-Host in NPM
- DNS: `fail2ban.example.org` auf die Adresse des Hosts zeigen lassen.
- NPM → **Hosts → Proxy Hosts → Add Proxy Host**:
| Feld | Wert |
|---|---|
| Domain Names | `fail2ban.example.org` |
| Scheme / Forward Hostname / Port | `http` · `fail2ban-webui` · `8080` |
| Block Common Exploits | an |
| SSL | Zertifikat anfordern (für interne Namen wie `*.int`: eigenes Zertifikat oder DNS-Challenge), *Force SSL*, *HTTP/2*, *HSTS* |
| Access List | empfohlen: nur deine IP-Adressen |
### 7. Testen
```bash
curl -sI https://fail2ban.example.org/login | grep -iE '^(HTTP|set-cookie)'
```
Erwartet: `HTTP/2 200` und ein Cookie mit `Secure; HttpOnly; SameSite=Lax`. Im Protokoll der
Weboberfläche steht nach einer Aktion die echte Client-Adresse, nicht die von NPM.
Optional: fehlgeschlagene Anmeldungen von fail2ban sperren lassen – siehe
[Login mit fail2ban absichern](docs/operations.md#login-mit-fail2ban-absichern)
(Banaction dort ebenfalls mit `chain=DOCKER-USER`).
## Dokumentation