By default, nginx will log visitor IP addresses in its access log. This is mostly useful for debugging purposes when you have some problem with your server. Also it’s often useful for mitigating bot attacks, hacking attempts, or other security-related issues.

Cloudflare is another DNS-level tool that can be used to speed up your website performance, increase security of your website, and many others. This time we will focus on cloudflare’s basic function called Cloudflare proxy. 

In the picture above you can see whether the DNS record is proxied through cloudflare. When you enable proxy, all visitor requests won’t directly hit your webserver and the actual server IP will be hidden. In contrast to traditional DNS (or, in Cloudflare they call it “DNS only”), we can usually know what is the actual server IP which serves a specific domain. This cloudflare proxy is good for both security and speed. Good for security because the actual server IP will remain hidden for the whole world, and good for speed because Cloudflare will acts as a “proxy” that will serve HTTP requests from cloudflare cache (if any). 

However, this proxy thing can sometimes cause a problem. One of them is this that we’re discussing in this article. If we enable proxy, then it’s gonna be the cloudflare proxy servers that will actually hit our server, not the real customer. That way, nginx will record cloudflare’s IP addresses instead of the visitor’s. To address this problem, we can apply some simple nginx configuration so that it will record the real customer IP. We assume that you already have a website running on nginx webserver and you have registered your domain on cloudflare.

Prerequisites:

  1. Nginx with http_realip_module module (should come by default in standard nginx installation)

Steps:

  1. Edit your site’s nginx config:
    vim /etc/nginx/sites-enabled/your-nginx-config-here
  2. Add the following lines. This list of IPs might change. Please check here for an up-to-date list.

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/13;

set_real_ip_from 104.24.0.0/14;

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 2c0f:f248::/32;

set_real_ip_from 2a06:98c0::/29;

#use any of the following two

real_ip_header CF-Connecting-IP;

#real_ip_header X-Forwarded-For;

  1. Save & quit
  2. Reload nginx
    sudo systemctl reload nginx.service

That’s it! Now you should be able to see the actual visitor IP under your nginx’s access log. Let us know if it works!