Home  »  ArticlesGuidesHow ToTechnology   »   Get the Real Client IP Address With Cloudflare CF-Connecting-IP in Apache | PHP

Get the Real Client IP Address With Cloudflare CF-Connecting-IP in Apache | PHP

Cloudflare is a website security service from a company of the same name that provides content delivery network and DDoS mitigation services. For several good reasons, you want to know the Real Client IP Address of your visitors.

With Cloudflare like any proxy, the webserver will not be able to tell what the visitor’s IP address is. This can open up several security issues because your Apache access and error logs will not show the correct IP but rather those of the Cloudflare infrastructure.

It also becomes difficult to define IP restrictions in your web server configuration, .htaccess, or even in PHP scripts.

Real Client IP Address Using CF-Connecting-IP

To solve this problem, Cloudflare sends the real client IP as CF-Connecting-IP in the HTTP header. CF-Connecting-IP provides the real client (visitor) IP address to the origin web server. cf-connecting-ip contains a special Cloudflare IP 2a06:98c0:3600:0:0:0:0:103 when the request originates from a Cloudflare Workers subrequest instead of the visitor’s true IP.

This works similar to the x-forwarded-for header which is used by proxy servers to tell the origin of any HTTP servers involved in relaying the request between the user and the origin.

There are some differences between CF-Connecting-IP and x-forwarded-for headers. With x-forwarded-for, you may see one or multiple sets of IP addresses in this header while CF-Connecting-IP will always contain one IP.

If Cloudflare does not receive the x-forwarded-for header from the client it will pass the same value as CF-Connecting-IP to the origin web server.

Cloudflare recommends your logs or applications look at CF-Connecting-IP or True-Client-IP instead of X-Forwarded-For since CF-Connecting-IP and True-Client-IP have a consistent format containing only one IP.

How to Handle CF-Connecting-IP on the Origin Server

We can retrieve the value of CF-Connecting-IP on the origin web server by enabling Apache’s mod mod_remoteip.

First, you need to enable remoteip on your server. In Ubuntu/Debian as well as CentOS/RHEL based systems run the following commands:

$ sudo a2enmod remoteip

Then restart Apache:

$ sudo systemctl restart apache2

Edit Apache Configs to Define Trusted Proxies

To pass the real client IP address from Cloudflare to Apache, we need to define the RemoteIPHeader directive as CF-Connecting-IP in the remoteip configuration file remoteip.conf.

Create the remoteip.conf configuration file by running this command in Ubuntu/Debian Linux systems.

$ sudo nano /etc/apache2/conf-enabled/remoteip.conf

On CentOS/RHEL Linux systems run this:

$ sudo nano /etc/httpd/conf.d/remoteip.conf

Add RemoteIPHeader CF-Connecting-IP as the first line and then a list of trusted Cloudflare proxies below it as RemoteIPTrustedProxy directives.

We do the above to mitigate hackers trying to spoof CF-Connecting-IP in the HTTP header by making sure that Apache knows which proxies to trust.

You can find an updated list of these IP addresses for Cloudflare IPv4 Proxies and Cloudflare IPv6 Proxies respectively.

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
RemoteIPTrustedProxy 103.22.200.0/22
RemoteIPTrustedProxy 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18
RemoteIPTrustedProxy 108.162.192.0/18
RemoteIPTrustedProxy 190.93.240.0/20
RemoteIPTrustedProxy 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22
RemoteIPTrustedProxy 198.41.128.0/17
RemoteIPTrustedProxy 162.158.0.0/15
RemoteIPTrustedProxy 104.16.0.0/13
RemoteIPTrustedProxy 104.24.0.0/14
RemoteIPTrustedProxy 172.64.0.0/13
RemoteIPTrustedProxy 131.0.72.0/22
RemoteIPTrustedProxy 2400:cb00::/32
RemoteIPTrustedProxy 2606:4700::/32
RemoteIPTrustedProxy 2803:f800::/32
RemoteIPTrustedProxy 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32
RemoteIPTrustedProxy 2a06:98c0::/29
RemoteIPTrustedProxy 2c0f:f248::/32

Save and exit then restart Apache.

$ sudo systemctl restart apache2

Note: If Apache doesn’t detect CF-Connecting-IP in the HTTP header (e.g. if Cloudflare is turned off or not configured for a particular Virtual Host), it will fall back to the Remote Address REMOTE_ADDR.

If Apache detects CF-Connecting-IP but it is coming from an IP not defined in RemoteIPTrustedProxy, Apache will fall back to the REMOTE_ADDR.

Verify the Apache Access and Error Logs

If you find that your access and error logs are showing the Cloudflare proxy IP instead of the remote user IP then you will need to complete these steps.

Note: You can verify by visiting your website then checking the logs for your IP for example:

$ sudo tail /var/log/apache2/access.log -n 20

To fix the issue in case it’s not your IP that is being logged, edit apache2.conf like so:

$ sudo nano /etc/apache2/apache2.conf

The search type CTRL + W to search for LogFormat.

The default log format should look something similar to below:

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Change the %h variable to %a, which is the Client IP as defined by the mod_remoteip module. The %h variable is the Remote IP.

Your LogFormat entries should look like this now:

LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Save and exit the file then restart Apache:

$ sudo systemctl restart apache2

Access the website again then view the access log to see if it is now logging the correct IP:

$ sudo tail /var/log/apache2/access.log -n 20

Get the Real Client IP Address From Within PHP

To get the real client IP address in PHP using the following:

// real IP of visitor
echo $_SERVER["HTTP_CF_CONNECTING_IP"]; 

//country of visitor
echo $_SERVER["HTTP_CF_IPCOUNTRY"]; 

//cloudflare IP
echo $_SERVER["REMOTE_ADDR"];

We retrieve the $_SERVER[“REMOTE_ADDR”] to verify that it contains an actual Cloudflare proxy IP address just in case a bad actor has faked the CF-Connecting-IP header if they have connected directly to the server.

Get the list of Cloudflare Ip addresses from the links below:

Ref: [ 1 ]

Found this article interesting? Follow Brightwhiz on Facebook, Twitter, and YouTube to read and watch more content we post.

Available under:
Articles, Guides, How To, Technology