diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..45fdee3 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,111 @@ +# F2B Control Center — FAQ + +--- + +### Why do I keep seeing Cloudflare IPs attacking me? + +You're not — those are Cloudflare's proxy servers, not attackers. + +When your domain is proxied through Cloudflare, all traffic reaches your server *from* Cloudflare's IP ranges, not from the real visitor. Without extra configuration, Nginx logs the Cloudflare IP as the client — which means fail2ban would ban Cloudflare instead of the actual bad actor, and you'd eventually block yourself. + +The fix is telling Nginx to trust Cloudflare as a proxy and extract the real visitor IP from the `X-Forwarded-For` header instead. When this is set up correctly, NPM logs show a `[Client X.X.X.X]` field with the real IP — which is exactly what F2B Control Center reads for scanning and banning. + +**How to fix it — NPM custom Nginx config:** + +In Nginx Proxy Manager, open the proxy host for your domain → **Advanced** tab → paste this into the **Custom Nginx Configuration** box: + +```nginx +# Trust Cloudflare proxy IPs and extract the real visitor IP +set_real_ip_from 103.21.244.0/22; +set_real_ip_from 103.22.200.0/22; +set_real_ip_from 103.31.4.0/22; +set_real_ip_from 104.16.0.0/12; +set_real_ip_from 108.162.192.0/18; +set_real_ip_from 131.0.72.0/22; +set_real_ip_from 141.101.64.0/18; +set_real_ip_from 162.158.0.0/15; +set_real_ip_from 172.64.0.0/13; +set_real_ip_from 173.245.48.0/20; +set_real_ip_from 188.114.96.0/20; +set_real_ip_from 190.93.240.0/20; +set_real_ip_from 197.234.240.0/22; +set_real_ip_from 198.41.128.0/17; +set_real_ip_from 2400:cb00::/32; +set_real_ip_from 2606:4700::/32; +set_real_ip_from 2803:f800::/32; +set_real_ip_from 2405:b500::/32; +set_real_ip_from 2405:8100::/32; +set_real_ip_from 2a06:98c0::/29; +set_real_ip_from 2c0f:f248::/32; +real_ip_recursive on; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header CF-Connecting-IP $remote_addr; +``` + +Save and reload. Your NPM access logs will now show the real client IP in the `[Client X.X.X.X]` field, and F2B Control Center will ban the actual offender instead of Cloudflare. + +> **Note:** Cloudflare occasionally updates their IP ranges. The current full list is always at [cloudflare.com/ips](https://www.cloudflare.com/ips/). + +--- + +### Do I need to whitelist Cloudflare IPs? + +No — once the `set_real_ip_from` config above is in place, Nginx transparently rewrites the client IP before fail2ban ever sees the log line. Cloudflare's IPs won't appear in your ban lists at all. + +If you set this up *after* already accumulating bans against Cloudflare IPs, check your whitelist and manually remove any Cloudflare ranges that snuck in. + +--- + +### Will this work without Cloudflare? + +Yes. If your server is exposed directly (no CDN), the `[Client X.X.X.X]` field will just show the connecting IP as-is. No special config needed — everything works out of the box. + +If you use a different CDN or reverse proxy upstream of NPM, add that proxy's IP ranges to `set_real_ip_from` instead of Cloudflare's. + +--- + +### Bans aren't blocking traffic — what's wrong? + +The most common cause is a missing kernel module. Check that `xt_string` is loaded on the host: + +```bash +lsmod | grep xt_string +``` + +If it's not listed: + +```bash +modprobe xt_string +echo xt_string >> /etc/modules # persist across reboots +``` + +Then restart the container. The `xt_string` module is required for the `X-Forwarded-For` header matching rule in the DOCKER-USER chain. + +--- + +### New proxy hosts aren't being monitored — why? + +Fail2ban only picks up log files that exist when it starts. If you add a new proxy host in NPM after the container is already running, its log file won't be watched automatically. + +F2B Control Center includes a `logwatch` process that polls for new `proxy-host-*_access.log` files every 30 seconds and reloads fail2ban automatically when it finds one. This handles the common case, but there may be a short delay before a brand-new host is monitored. + +If you want to force it immediately: + +```bash +docker exec f2b-control-center fail2ban-client reload +``` + +--- + +### How do I reset everything back to defaults? + +Remove the persistent config volume — the container will repopulate it from the bundled defaults on next start: + +```bash +docker compose down +docker volume rm f2b-control-center_f2b-config +docker compose up -d +``` + +This resets jail settings and filters only. Ban history and exemptions (stored in the `f2b-data` volume) are unaffected. To wipe those too, also remove `f2b-control-center_f2b-data`. diff --git a/README.md b/README.md index 8d12134..a092fe4 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,14 @@ This started as a personal setup I built to protect my own self-hosted services. The migration from personal scripts into a clean, shareable Docker project — packaging, entrypoint initialization, the dashboard UI, and this documentation — was done with significant help from [Claude](https://claude.ai) (Anthropic). If you're curious what AI-assisted development looks like in practice, this project is a fairly honest example. +If this saves you some headaches, you can buy me a coffee: [ko-fi.com/manicmedia](https://ko-fi.com/manicmedia) + +--- + +## FAQ + +See **[FAQ.md](FAQ.md)** for common questions including how to fix Cloudflare IP logging, bans not blocking traffic, and resetting to defaults. + --- ## License