Stop using CF-Connecting-IP in your PHP scripts

Image: @LincolnGroup, 2013, Pixabay

If you have a setup using Cloudflare (or any other reverse proxy service) and you are using $_SERVER[“HTTP_CF_CONNECTING_IP”] or such thing istead of $_SERVER[“REMOTE_ADDR”] in PHP to get the real visitor IP, as suggested on some forums, then you are on the wrong path. This advice, I heve seen on some forums, is definitely not the correct way of getting the real visitor IP.

Ideally, in PHP, $_SERVER[“REMOTE_ADDR”] should always reflect real visitor IP, not Cloudflare’s IP (or your reverse Proxy service’s IP). Using $_SERVER[“HTTP_CF_CONNECTING_IP”] in PHP should not be a workaround.

If your http server does not know the real visitor IP, then this will have consequences:

  • Your web server logs will be messed up with Cloudflare IP addresses.
  • Any connection/resource limit on http server will not work correctly.
  • Your PHP script can be cheated (with fake IP addresses) if Cloudflare IP range check is not implemented.
Image: @Cloudflare

Cloudflare sends visitor IP in CF-Connecting-IP header and this must be ideally handled at server level, and not by PHP. For Nginx ngx_real_ip modüle, and for Apache, mod_remoteip or mod_cloudflare module handles this job pretty well.

With Nginx this should be achieved as:

real_ip_header CF-Connecting-IP;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 188.114.96.0/20;
...

With such configuration the web server gets the real ip from CF-Connecting-IP, logs the real IP correctly, applies IP specific connection limits without any problems, passes the correct IP to PHP’s , $_SERVER[“REMOTE_ADDR”] and internally handles all the situation with real visitor IP.

The set_real_ip_from directives here, define the trusted addresses that are known to send correct replacement addresses to prevent anyone spoofing her IP by sending fake CF-Connecting-IP headers.

The only problem here is dynamically updating Cloudflare IP address ranges. There is a ready-to-use script and also a Docker image which can be used for this purpose.

Apache has also its own generic solution, mod_remoteip:

<IfModule mod_remoteip.c>
    RemoteIPHeader CF-Connecting-IP
    RemoteIPTrustedProxy 103.21.244.0/22
    RemoteIPTrustedProxy 141.101.64.0/18
    RemoteIPTrustedProxy 188.114.96.0/20
    ...
</IfModule>

If the CDN here is just Cloudflare, there is also an official tool which does the same thing for Apache, called mod_cloudflare.

Source: https://volkan.xyz

 

You can share this blog post only by giving appropriate credit as described at Terms & Conditions.

 

Leave a Reply

Your email address will not be published. Required fields are marked *