Files
fail2ban-ui/docs/reverse-proxy.md

122 lines
3.6 KiB
Markdown

# Reverse Proxy Deployment Guide
This guide provides production-redy guidance for running Fail2Ban UI behind a reverse proxy.
## Why this matters
Fail2Ban UI includes administrative capabilities and callback endpoints. A reverse proxy lets you apply TLS, access controls, and standardized HTTP security policies before traffic reaches the UI.
## Basic architecture
```text
Browser / Fail2Ban hosts
|
HTTPS (443)
|
Reverse Proxy (TLS termination)
|
HTTP (127.0.0.1:8080)
|
Fail2Ban UI
```
Recommended runtime settings for the above example:
- `BIND_ADDRESS=127.0.0.1` (when proxy and UI run on the same host)
- `PORT=8080` (or another local port)
- `OIDC_ENABLED=true` for user authentication (optional but recommended)
## Reverse proxy requirements
For correct UI behavior (including WebSocket live updates), the proxy must:
1. Preserve `Host` and `Origin` consistency.
2. Allow WebSocket upgrades on `GET /api/ws`.
3. Forward client IP context (`X-Forwarded-For`, `X-Forwarded-Proto`).
## Nginx reference configuration
Use this as a baseline and adapt to your hostnames and certificates.
```nginx
server {
listen 80;
server_name fail2ban.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name fail2ban.example.com;
ssl_certificate /etc/letsencrypt/live/fail2ban.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fail2ban.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
# Optional strict transport security (don't forget to preload via -> https://hstspreload.org/)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Referrer-Policy no-referrer always;
# Optional source allowlist
# allow 10.0.0.0/8;
# allow 192.168.0.0/16;
# deny all;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# Proxy WebSocket endpoint
location /api/ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
```
## Caddy reference configuration
```caddy
fail2ban.example.com {
encode zstd gzip
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer"
}
reverse_proxy 127.0.0.1:8080
}
```
Caddy automatically handles TLS and WebSocket upgrades for this basic setup.
## Validation checklist / some tests
1. Validate UI: `curl -Ik https://fail2ban.example.com/`
2. Validate API reachability: `curl -s https://fail2ban.example.com/api/version`
3. Validate WebSocket in browser dev tools:
- status `101 Switching Protocols` for `/api/ws`
- live ban/unban events update without refresh
4. Validate callback path from managed Fail2Ban hosts to configured `CALLBACK_URL`