It's very common to track user IP, Location or Logging real visitor IP's but having cloud flare in the front you can see in your server logs that you are not receiving real users IP but instead you are getting CloudFlare IP's. This post is to guide you how to restore your visitors IP address from Cloudflare in Nginx, Apache2, PHP, NodeJS or any other stack.

By Default you will receive CF-Connecting-IP along with X-Forwarded-For in your headers when you receive a request from cloudflare. We can use these two headers to get the real client IP

Make sure you don't get confused with CloudFlare True-Client-IP enterprise feature. This comes for free with cloudflare.

Nginx Config to Get the Real Client IP Address

use these two nginx directive to config cloudflare as shown in the nginx_cloudflare.conf gist.

set_real_ip_from      IP_HERE;
real_ip_header        CF-Connecting-IP;

Configure Apache2

Since Apache 2.4 we can use mod_remoteip module to trust clouflare proxy

Enable mod_remoteip

sudo a2enmod remoteip

Copy this apache_cloudflare.conf from the snippet

/etc/apache2/conf-enabled/nginx_cloudflare.conf

Restart apache

sudo systemctl restart apache2

Validating the Client IP

As hacker might try to spoof the headers we should validate CF-Connecting-IP with the remote address, your server might reject this header. In this case you need to fallback to server remote address

Retrieve In PHP

$_SERVER["HTTP_CF_CONNECTING_IP"] ?? $_SERVER["REMOTE_ADDR"]

Retrieve In Node/Express JS

req.header('CF-Connecting-IP') 
|| req.header('X-Forwarded-For') 
|| req.connection.remoteAddress;

Bonus

CloudFlare also provides another header CF-IPCountry Which you can use the get the country code of the real visitor.