nginx IP rules beyond DDoS guard

I use ngx_http_access_module‘s allow/deny directives to protect sensitive parts of my websites from public access. But if a website is protected by CloudFlare, or same-scheme DDoS protection/CDN provider, your nginx will get only CloudFlare’s IPs, so your blocking (or any another IP-based, e.g. GeoIP) rules will not work. This HOWTO is written for CloudFlare.

P.S. Please check your access.log to ensure if you are really getting the wrong IPs before doing something.

So, we can use built-in nginx module ngx_http_realip_module to handle this. It provides the ability to get the real client’s IP address based on CloudFlare’s headers.

We’ll use the set_real_ip_from directive. You can get CloudFlare’s subnet list from this official page, which is regularly updated. We need to buld the list which looks like this, for example:

Please DO NOT copy this and use actual IP list provided by CloudFlare, this may be incorrect

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/12;
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 199.27.128.0/21;

..And add the header real_ip_header X-Forwarded-For;. This will throw the real IP to backend.
Now, we’ll add this all to our virtualhost config on server config level. You also can use it in location level, but be sure that you put it in all the locations, including defined by regular expressions. Example:

server {
<...> there goes your virtualhost config <...>

        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/12;
        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 199.27.128.0/21;

        real_ip_header X-Forwarded-For;

        location / {
<...> and here the following config below <...>

Now, check your config with nginx -t and restart the web server to apply the changes.
Now nginx received the valid client IPs from CloudFlare and your rules will work correctly.

Leave a Reply

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