gitea 60bb6abe4f Add two-tier IP exemption system; fix scan button to use /api/exempt
- 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>
2026-02-20 18:49:15 +00:00

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_string kernel 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-For header 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

Description
No description provided
Readme MIT 844 KiB
Languages
JavaScript 34%
HTML 30.1%
CSS 22.2%
Shell 7.7%
Dockerfile 6%