Nginx, Varnish and optional CloudFlare: Real IPs

If you use a proxy such as Varnish or CloudFlare, your web server isn’t going to see visitor’s real IP address, it’ll see the IP of your proxy (for example, Varnish would be 127.0.0.1 if running on the same box as your web server).

You can easily find instructions to fix this for Varnish or CloudFlare or both online, but I didn’t see any articles about fixing it for servers that have sites in front of cloudflare and sites that aren’t. If you use the CF-Connecting-Ip header, it’ll break for sites accessed directly, only showing 127.0.0.1 (from Varnish).

Here’s my fix:

http {
 ### Cloudflare

 set_real_ip_from 204.93.240.0/24;
 set_real_ip_from 204.93.177.0/24;
 set_real_ip_from 199.27.128.0/21;
 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;
 set_real_ip_from 141.101.64.0/18;
 set_real_ip_from 108.162.192.0/18;
 set_real_ip_from 190.93.240.0/20;
 set_real_ip_from 188.114.96.0/20;
 set_real_ip_from 197.234.240.0/22;
 set_real_ip_from 198.41.128.0/17;
 set_real_ip_from 162.158.0.0/15;
 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 127.0.0.1;
 real_ip_header X-Forwarded-For;
 real_ip_recursive on;

 ...
}

The X-Forwarded-For header is pretty well known, but CloudFlare prepends the original IP to the header, and Nginx pulls the last IP so you only get CloudFlare’s IP. The real_ip_recursive option makes Nginx look through each one until it finds one not listed in the set_real_ip_from whitelist. You’ll now get the right IP from Varnish and/or CloudFlare!

You can get the latest whitelist of IPs for CloudFlare fromĀ https://www.cloudflare.com/ips. Don’t forget to add 127.0.0.1 so Nginx will pull the headers from Varnish!

One Reply to “Nginx, Varnish and optional CloudFlare: Real IPs”

Leave a Reply