Web interface to view, ban and unban fail2ban IPs on several hosts via SSH, generalised from the private f2b-web tool. - Web UI (Flask/Waitress): hosts.yaml, local/OIDC/proxy authentication, English/German UI, origin map, optional Loki/Grafana/GeoIP, CLI helpers - Agent f2b-webctl with install.sh/uninstall.sh (dedicated user + sudo, from= restriction, protected networks, manual jail) - Hardened Docker image, examples, documentation, smoke test, testbed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
89 lines
4.3 KiB
Markdown
89 lines
4.3 KiB
Markdown
# fail2ban-webui
|
||
|
||
A small, self-hosted web interface to **view, ban and unban fail2ban IPs on several hosts** –
|
||
bare metal, VMs, LXC containers or Docker hosts.
|
||
|
||
- One page for all hosts: current bans per jail, origin (GeoIP) with a world map, search and filters
|
||
- Ban an IP permanently on any selection of hosts, unban per jail or everywhere
|
||
- Audit log of every action (who, when, from where)
|
||
- Optional: log history per IP from **Loki**, links into **Grafana**
|
||
- Sign-in with a local user, **OpenID Connect** (e.g. Authentik) or your reverse proxy
|
||
- English and German UI, more languages via one JSON file
|
||
- Runs as a hardened container (read-only, no capabilities, non-root), `amd64` and `arm64`
|
||
|
||
```
|
||
Browser ──HTTPS──▶ reverse proxy ──▶ fail2ban-webui (Docker)
|
||
│ SSH, one restricted key
|
||
┌─────────────────────┼─────────────────────┐
|
||
▼ ▼ ▼
|
||
host A (bare) LXC container Docker host
|
||
f2b-webctl f2b-webctl f2b-webctl
|
||
fail2ban fail2ban fail2ban
|
||
```
|
||
|
||
The web UI never gets a shell on your hosts. Every host runs a tiny agent,
|
||
[`f2b-webctl`](agent/f2b-webctl), as SSH *forced command*. It only knows
|
||
`list`, `ban <ip>`, `unban <jail> <ip>`, `unban-all <ip>` and `version`, refuses to ban
|
||
private networks, the host's own addresses or anything on its protected list, and logs
|
||
every action to syslog. Access to the fail2ban socket would be equivalent to root –
|
||
the agent is the security boundary, not the web UI.
|
||
|
||
## Quick start
|
||
|
||
```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
|
||
|
||
docker compose run --rm -it fail2ban-webui hash-password # paste the line into .env
|
||
docker compose run --rm fail2ban-webui keygen # public key for the agents
|
||
# on every fail2ban host: install the agent (docs/agent.md), then:
|
||
docker compose run --rm -it fail2ban-webui keyscan
|
||
docker compose run --rm fail2ban-webui check
|
||
docker compose up -d
|
||
```
|
||
|
||
The UI listens on `127.0.0.1:8080` – put a reverse proxy with TLS in front of it.
|
||
|
||
## Documentation
|
||
|
||
| | |
|
||
|---|---|
|
||
| [Installation](docs/installation.md) | web UI step by step, from `mkdir` to the first login |
|
||
| [Agent](docs/agent.md) | installing `f2b-webctl` on bare metal, LXC and Docker hosts |
|
||
| [Configuration](docs/configuration.md) | every setting in `.env` and `hosts.yaml` |
|
||
| [Authentication](docs/authentication.md) | local login, OpenID Connect (Authentik), reverse-proxy auth |
|
||
| [Reverse proxy](docs/reverse-proxy.md) | Nginx Proxy Manager, Caddy, Traefik, nginx |
|
||
| [Operations](docs/operations.md) | logs, updates, backups, troubleshooting |
|
||
| [Development](docs/development.md) | local testbed, tests, adding a language |
|
||
| [Security](SECURITY.md) | security model and reporting vulnerabilities |
|
||
|
||
## Requirements
|
||
|
||
- Web UI: Docker with Compose v2, `amd64` or `arm64`
|
||
- Every fail2ban host: fail2ban ≥ 0.11 (start/end times need `--with-time`), `python3`,
|
||
`sshd`, `sudo` (or a root key), `bash`
|
||
|
||
## License
|
||
|
||
[MIT](LICENSE). IP geolocation by [DB-IP Lite](https://db-ip.com) (CC BY 4.0), downloaded
|
||
only when `GEOIP_AUTO_DOWNLOAD=1`. World map from [Natural Earth](https://www.naturalearthdata.com)
|
||
(public domain), bundled with the app.
|
||
|
||
---
|
||
|
||
<p align="center">
|
||
🏰 <a href="https://retronerd.at">Website</a> ·
|
||
🐘 <a href="https://social.retronerd.at/@schiwagoa">Mastodon</a> ·
|
||
🔒 <a href="https://retronerd.at/datenschutzerklaerung/">Datenschutz</a> ·
|
||
💬 <a href="https://helpdesk.retronerd.at/open.php">Support</a>
|
||
</p>
|
||
|
||
<p align="center">
|
||
<img src="https://dl.retronerd.at/Bilder/cat-footer.png" alt="" width="100%">
|
||
</p>
|
||
|
||
<p align="center">© Thomas Werner Schwaighofer · retronerd.AT · <a href="LICENSE">MIT Lizenz</a></p>
|