How to restore your visitors IP addresses when using Cloudflare & NGINX

Paul November 5th 2014

If you've found this page and are looking for restoring your visitor IP's / REMOTE_ADDR and are using Apache take a look at mod_cloudflare for doing everything you need automatically as far as I know. If you still need to restore your REMOTE_ADDR then scroll down.

CLOUDFLARE

Cloudflare is a fantastic service available from free. It offers a nice bunch of tools to make your site faster via their CDN network and more secure through their various protection measures and SSL.  It does this by passing the majority of traffic (depending on your DNS settings) to your site through proxies within their network, caching static content and serving it from the best location according to where your users are globally.  This means you can offer a great serving of your web content to anyone around the globe without the worry of different load-times etc.

 

Unfortunately there is a small annoying issue if your website / service uses visitor IP's in order to determine specific actions or record vital stats.  All requests coming into your website are reverse proxied, therefore only cloudflares IP address ranges will show up in your logs instead of the visitor IP.

 

FIXING NGINX.

Gather uses nginx for most of its live services (better scalability than Apache). Unfortunately there isn't a mod_cloudflare available, instead nginx has a very cool module called http-real-ip.  This module allows you to specify a range of IP addresses along with a header which can map the original visitor IP back into your request.

 

Whenever a request is sent to your site via Cloudflare, the original IP address will be included in the X-Forwarded-For header and/or CF-Connecting-IP header. If you don't use any other proxies on your site use the latter.

 

Depeding on your setup, insert the following into your nginx configuration.

Note that this is valid within http, server, location contexts, so if you're on a shared host this should not matter.

 

# Cloudflare 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 104.16.0.0/12; 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; real_ip_header CF-Connecting-IP;

Restart/reload nginx and your IP's will now be your visitors original IP.

 

FIXING PHP /

$_SERVER['REMOTE_ADDR']

Next if you're doing anything fancy with PHP and wish to check the visitor IP, whilst keeping support for when you turn off Cloudflare, place the following code somewhere in your PHP startup.  i.e for Wordpress a good place to put this would be at the start of your config.php file.

//restore original visitor IP if from Cloudflare if ( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ){ $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP']; }
Author Paul Technical Director

Technical Director & Co-founder of Gather. Paul is a Manchester born computer scientist with broad full stack web & mobile application skillset, he has helped shaped Gather's technology, and build many large scale web applications.