Introduction
When Nginx sits behind Cloudflare, the origin sees Cloudflare edge connections by default. If the real_ip module is not configured correctly, access logs, fail2ban rules, geographic controls, and rate limiting all work against Cloudflare IPs instead of the real visitor address.
Symptoms
- Access logs show only Cloudflare edge addresses instead of client IPs
- Rate limiting blocks large groups of unrelated users at once
- Security tools such as fail2ban keep banning Cloudflare IP ranges
- The problem started after putting the site behind Cloudflare or changing proxy settings
Common Causes
- Nginx does not trust Cloudflare proxy IP ranges
- The wrong header is configured for
real_ip_header - Cloudflare IP ranges were configured once but never updated
- Real IP handling is defined in one server block but missing in another
Step-by-Step Fix
- 1.Confirm which IP address Nginx is logging right now
- 2.Check the live access log before changing the configuration so you can verify the fix later.
tail -n 20 /var/log/nginx/access.log- 1.Trust the Cloudflare proxy ranges and use the correct header
- 2.Cloudflare sends the original client address in
CF-Connecting-IP, which Nginx should trust only for Cloudflare proxy ranges.
set_real_ip_from 173.245.48.0/20;
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;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;- 1.Reload Nginx and test with a fresh request
- 2.A config change without a reload leaves the origin serving the old behavior.
nginx -t && systemctl reload nginx
curl -I https://example.com- 1.Verify the logs and security controls now see the visitor IP
- 2.Check logs, geo rules, and rate limiting after the reload so you know downstream controls are using the corrected address.
tail -n 20 /var/log/nginx/access.logPrevention
- Keep Cloudflare IP ranges updated as part of proxy hardening maintenance
- Centralize
real_ipconfiguration in shared Nginx includes - Re-test logging and rate limiting whenever a CDN or reverse proxy changes
- Avoid trusting forwarded IP headers from arbitrary sources