# Reverse Proxy Der Container liefert reines HTTP auf Port 8080 (im Beispiel veröffentlicht als `127.0.0.1:8080`). Davor gehört ein Reverse Proxy mit TLS; in der `.env` dazu setzen: ```ini PUBLIC_URL=https://fail2ban.example.org TRUSTED_PROXY_HOPS=1 ``` Der Proxy muss `Host` unverändert weitergeben und `X-Forwarded-For` sowie `X-Forwarded-Proto` setzen – alle Beispiele unten tun das. Den Zugriff am Proxy zusätzlich auf bekannte IP-Adressen zu beschränken kostet wenig und ist dringend empfohlen. ## Nginx Proxy Manager **Hosts → Proxy Hosts → Add Proxy Host** | Feld | Wert | |---|---| | Domain Names | `fail2ban.example.org` | | Scheme / Forward Hostname / Port | `http` · IP des Docker-Hosts (oder `127.0.0.1`, wenn NPM im Host-Netzwerk läuft) · `8080` | | Block Common Exploits | an | | SSL | Zertifikat anfordern, *Force SSL*, *HTTP/2*, *HSTS* | | Access List | optional: eine Access List mit deinen IP-Adressen (*Satisfy any* aus) | Läuft NPM auf demselben Host in einem anderen Docker-Netz, den Port der Oberfläche an die LAN-Adresse des Hosts binden (z. B. `"192.168.1.10:8080:8080"`) oder die Oberfläche an das Netz von NPM hängen und `fail2ban-webui:8080` als Ziel verwenden. Antwort-Header gehören nach **Advanced → Custom Nginx Configuration**; das NPM-Image enthält das Modul *headers-more*, das sie auch auf weitergeleitete Antworten anwendet: ```nginx more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains"; ``` (CSP, `X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy` und `Cache-Control` setzt die App selbst.) ## Caddy ```caddy fail2ban.example.org { @allowed remote_ip 203.0.113.0/24 2001:db8::/32 handle @allowed { reverse_proxy 127.0.0.1:8080 } respond 403 } ``` Caddy setzt `X-Forwarded-For`/`-Proto` automatisch. ## Traefik (Docker-Labels) Den Container an das Netz von Traefik hängen und Labels setzen, statt den Port zu veröffentlichen: ```yaml services: fail2ban-webui: # … as in the example compose file, without "ports:" labels: - traefik.enable=true - traefik.http.routers.f2bwebui.rule=Host(`fail2ban.example.org`) - traefik.http.routers.f2bwebui.entrypoints=websecure - traefik.http.routers.f2bwebui.tls.certresolver=letsencrypt - traefik.http.routers.f2bwebui.middlewares=f2bwebui-ipallow - traefik.http.middlewares.f2bwebui-ipallow.ipallowlist.sourcerange=203.0.113.0/24 - traefik.http.services.f2bwebui.loadbalancer.server.port=8080 networks: - fail2ban-webui.dockernetwork.local - traefik ``` ### Traefik mit Authentik Forward Auth (Proxy-Modus) ```yaml - traefik.http.routers.f2bwebui.middlewares=authentik@docker ``` ```ini AUTH_MODE=proxy AUTH_PROXY_HEADER=X-authentik-username AUTH_PROXY_ALLOWED_IPS=
/32 AUTH_PROXY_LOGOUT_URL=https://fail2ban.example.org/outpost.goauthentik.io/sign_out ``` ## nginx ```nginx server { listen 443 ssl; http2 on; server_name fail2ban.example.org; ssl_certificate /etc/letsencrypt/live/fail2ban.example.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/fail2ban.example.org/privkey.pem; allow 203.0.113.0/24; deny all; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 90s; # several slow agents can take a while } } ``` ## Prüfen ```bash curl -sI https://fail2ban.example.org/login | grep -iE '^(HTTP|content-security|set-cookie)' ``` Erwartet werden `HTTP/2 200`, der Header `Content-Security-Policy` und ein Sitzungs-Cookie mit `Secure; HttpOnly; SameSite=Lax`. Fehlt `Secure` am Cookie, beginnt `PUBLIC_URL` nicht mit `https://`.