- Add EXEMPT_FILE, readExemptions/saveExemptions/isExempt/addExemption/removeExemption - Filter exempt IPs from scan results (still monitored by fail2ban) - buildBanList() appends exempt entries with jail:'exempt' - API: POST /api/exempt, DELETE /api/exempt/:ip, GET /api/exemptions - Frontend: [EXEMPT] filter tab, exempt jail color, REMOVE/ARREST/THREAT actions - Scan card [WHITELIST] button → [EXEMPT] calling /api/exempt (not ignoreip) - Fix isWhitelisted() to read only jail.local with proper CIDR matching - Fix readIgnoreIP() regex: \s* → [ \t]* to prevent cross-line capture Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
F2B Control Center
Fail2Ban + Nginx Proxy Manager in a single Docker container, with a web dashboard for monitoring and managing bans.
Pre-built filters detect bad bots, HTTP error spamming, and exploit probing against NPM logs. Bans are enforced via iptables (DOCKER-USER chain + INPUT), with optional Cloudflare WAF banning on top.
Requirements
- Docker + Docker Compose
- Linux host with iptables support
xt_stringkernel module on the host (modprobe xt_string)
Quick Start
git clone https://git.thisisfake.lol/mykey/f2b-control-center
cd f2b-control-center
Edit docker-compose.yml — at minimum review SUBNETS_TO_IGNORE. Then:
docker compose up -d
Dashboard at http://YOUR_HOST:4000
On first start the container installs the default Fail2Ban config into a persistent volume and begins monitoring NPM logs immediately.
Configuration
All settings are in docker-compose.yml. Required fields are uncommented. Optional features are commented out — uncomment and fill in to enable.
| Variable | Default | Description |
|---|---|---|
PORT |
4000 |
Dashboard port |
SUBNETS_TO_IGNORE |
RFC1918 ranges | CIDRs excluded from scanning and banning |
ABUSEIPDB_API_KEY |
(optional) | Enables threat scoring and auto-ban |
CF_EMAIL |
(optional) | Cloudflare account email — enables WAF banning |
CF_APIKEY |
(optional) | Cloudflare Global API Key |
Jails
| Jail | Trigger | Ban time |
|---|---|---|
badbot |
Known scanner/exploit user-agents | 24h |
http-errors |
15+ 4xx/5xx errors in 5 min | 1h |
npm-probe |
Exploit path probing (.env, wp-login, etc.) | 48h |
manual-bans |
Manual dashboard or CLI bans | Permanent |
recidive |
Repeat offenders (disabled by default) | 7d |
To customise jails:
docker exec -it f2b-control-center bash
vi /etc/fail2ban/jail.local
fail2ban-client reload
How Banning Works
The container uses network_mode: host so iptables rules affect the host network stack. Two rules are inserted per ban:
- DOCKER-USER — drops forwarded packets where the
X-Forwarded-Forheader matches the banned IP (catches traffic routed through Cloudflare/CDN) - INPUT — drops direct connections from the banned IP
Requires xt_string on the host:
modprobe xt_string
# to persist across reboots:
echo xt_string >> /etc/modules
Cloudflare WAF
Uncomment and fill in CF_EMAIL and CF_APIKEY in docker-compose.yml. The container detects these on first start and installs the Cloudflare action alongside iptables — no other changes needed.
Get your Global API Key at: https://dash.cloudflare.com/profile/api-tokens
Log Format
Filters expect NPM logs with the real client IP in a [Client X.X.X.X] field — the format NPM produces when behind Cloudflare or any proxy that forwards X-Forwarded-For.
Test a filter against your logs:
docker exec f2b-control-center \
fail2ban-regex /nginx-logs/proxy-host-1_access.log \
/etc/fail2ban/filter.d/http-errors.conf
Useful Commands
# View logs
docker compose logs -f
# Reload fail2ban config
docker exec f2b-control-center fail2ban-client reload
# Check jail status
docker exec f2b-control-center fail2ban-client status
# Manual ban / unban
docker exec f2b-control-center fail2ban-client set manual-bans banip 1.2.3.4
docker exec f2b-control-center fail2ban-client set manual-bans unbanip 1.2.3.4
Volumes
| Volume | Path | Contents |
|---|---|---|
f2b-data |
/data |
Ban history database |
f2b-config |
/etc/fail2ban |
Jail and filter config (survives image updates) |
| bind mount | /nginx-logs |
NPM log directory (read-only) |
License
MIT