When working behind the Cloudflare proxy, we need to make sure the client/visitor's real IP Address is passed correctly to our website application i.e, WordPress.
For example, for this website I use Cloudflare as a firewall and CDN service, Nginx as a reverse proxy, Apache as a web server, and WordPress as a content management system CMS.
Without passing the Client/Visitor's real IP address to our side (Linux Firewall, Web Server, Web Application, etc.. ) any hits to our system side may be logically considered as it is coming from Cloudflare proxy. and that may cause misconfiguring, misunderstanding, and taking the wrong action to mitigate attacks.
Now to get the client/visitor's real IP address, and maximum control access to our web server, we have to make a little configuration task on each side, at the same time we can successfully apply actions to mitigate attacks as we discussed in Catch The Bad Bots Which Cause High CPU Usage And Blocking Them In Simple 2 Steps tutorial.
Cloudflare side
By default, Cloudflare sends the visitor or client IP address in the CF-Connecting-IP
header, This header is passed from Cloudflare to the origin server side (T the server who received the request from the Cloudflare side).
What if the Client or visitor was accessed your website but using Proxy!?
For this case X-Forwarded-For
the header will be passed from Cloudflare with the Client's real IP Address and will append the proxy IP address after.
For example, if we received X-Forwarded-For: 203.0.113.1,198.51.100.101
the header from Cloudflare, the client's original and real IP address is 203.0.113.1, and 198.51.100.101 is the client proxy IP Address.
What if the Client or visitor has direct access to your website and does not use any proxy!?
The header X-Forwarded-For
will have an identical value to the CF-Connecting-IP
Cloudflare header.
Configure Nginx
The ngx_http_realip_module
Nginx module is enabled by default, but we can check that using the following command
# nginx -V 2>&1 | tr -- - '\n' | grep module modules path=/usr/lib/nginx/modules http_ssl_module http_stub_status_module http_realip_module http_auth_request_module http_v2_module http_dav_module http_slice_module http_addition_module http_flv_module http_geoip_module=dynamic
ngx_http_realip_module
can be configured in the HTTP, or server context.. so we can configure Cloudflare settings as the following:
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;
The Nginx module will change the client address to one sent in the CF-Connecting-IP
specified header field.
And all Cloudflare IP Addresses needs to be updated as they list them at the URL: https://www.cloudflare.com/ips/
Configure Apache
We will use Apache mod_remoteip
module.. as we can configure it for Apache 2.4 as the following
1- Enable Apache mod_remoteip
# a2enmod remoteip
2- Configure Apache mod_remoteip
Update your website configuration file, as an example for the default apache one, is located at : /etc/apache2/sites-available/000-default.conf
ServerAdmin webmaster@example.com DocumentRoot /var/www/html ServerName example.com RemoteIPHeader CF-Connecting-IP ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined
3- Update Apache LogFormat
Updete the LogFormat at the file /etc/apache2/apache2.conf
from
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Replaced by:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
By just replacing %h which present the Remote hostname or the IP address if HostnameLookups is set to Off <=> replaced with %a which present the requesting Client IP address.
4- Define Cloudflare trusted proxy addresses for mod_remoteip
Edit the file /etc/apache2/conf-available/remoteip.conf
And Append the following IP Address
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/12 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
As mentioned above, all Cloudflare IP Addresses needs to be updated as they list them at the URL: https://www.cloudflare.com/ips/
Now Enable the configuration and restart Apache.
# a2enconf remoteip Enabling conf remoteip. To activate the new configuration, you need to run: service apache2 reload # apache2ctl configtest Syntax OK # systemctl restart apache2
WordPress Configuration
Append the following code to your WordPress wp-config.php
file
/** Pass Client/Visitor Real IP Address From Cloudflare Side **/ if(array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER)){ $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP']; }
This Will Correct The Server Environment Variable REMOTE_ADDR
and add the correct Client/visitor's IP address stored in the Cloudflare header CF_CONNECTING_IP
.
Resource: Restoring original visitor IPs