How to use IP Geolocation Regulatory Compliance Data Feeds with Nginx and Apache | WhoisXML API



IP Geolocation Blog

How to use IP Geolocation Regulatory Compliance Data Feeds with Nginx and Apache?

There are two common ways to configure deny lists for Nginx:

  • With the use of the Nginx include module;
  • With the use of the Nginx geo module.

1. How to use data feeds with the Nginx include module?

The required configuration file should be either placed in the already included 'nginx/conf.d' folder or can be called directly by including it in the 'location' directive. Which folders are included currently can be checked in nginx.conf:

include /etc/nginx/conf.d/*.conf;

Example of ./mySite.conf if the deny list does not reside in the default config folder:

location / {
    include /etc/nginx/my_deny_nginx.conf;
    allow all;
    try_files $uri $uri @allowed;
    error_page 403 = @denied;
}
location @allowed {
    default_type text/html;
    return 200 'Your $REMOTE_ADDR is allowed';
}
location @denied {
    default_type text/html;
    return 403 'Your $REMOTE_ADDR is blocked';
}

Example of my_deny_nginx.conf:

deny 1.0.1.0/24;
deny 1.0.2.0/23;
deny 1.0.4.0/32;
deny 1.0.8.0/21;
deny 1.0.16.0/32;
deny 1.0.32.0/19;
deny 1.0.64.0/32;

Usage with rewrite module

Note that if you are using the Nginx’s rewrite module, it precedes include directives. In this case, use if statements. Example of the config with rewrite module usage (302 redirects):

location / {
include /etc/nginx/my_deny_nginx.conf;
allow all;
try_files $uri $uri @allowed;
error_page 403 = @denied;
return 302 https://$new-site$request_uri;
}

To overcome this, a redirect can be used inside the if statement. For example, redirect HTTP to HTTPS:

Without if statement:

server_name mySite.localhost.local;
     location ~^/[^/]+$ {
             return     302 https://$server_name$request_uri;
     }

With if statement:

server_name mySite.localhost.local;
     location ~^/[^/]+$ {
             if ($host = 'http://mySite.localhost.local' ) {
                     rewrite  ^/(.*)$  https://mySite.localhost.local/$1;
             }
     }

How to convert the data feed to Nginx deny list?

To create my_deny_nginx.conf:

  • Download the data feed in CIDR notation to your server;
  • Use the following bash script:
zcat geoipify_ofac_cidr_2023_01_23.txt.gz > geoipify_ofac_cidr_2023_01_23_uncompressed.txt
while IFS= read -r line; do echo "deny ${line};"; done <  geoipify_ofac_cidr_2023_01_23_uncompressed.txt > my_deny_nginx.conf
rm -f geoipify_ofac_cidr_2023_01_23_uncompressed.txt

2. How to use data feeds with the Nginx geo module

Prerequisites:

  • Nginx needs to be built with the geo module. You can check whether the Nginx was built with the geo module by running nginx -V and looking for the with-http_geoip_module flag. Also, you can check whether it’s enabled via '/nginx/modules-enabled';
  • Note that it works only with if clauses usage.

How to check:

Command: nginx -V 2>&1 | tr ' ' '\n' | egrep -i 'geo'
Output: --with-http_geoip_module=dynamic

Or:

Command: nginx -V 2>&1 | tr ' ' '\n' | egrep -i 'modules-path'
Output: --modules-path=/usr/lib/nginx/modules
Command: ls -lh /usr/lib/nginx/modules | grep geo
Output: -rw-r--r-- 1 root root  24K Nov 10 06:38 ngx_http_geoip_module.so
Command: cat /etc/nginx/modules-enabled/50-mod-http-geoip.conf
Output: load_module modules/ngx_http_geoip_module.so;

Example of ./mySite.conf if the deny list resides in the default config folder:

location / {
    if ( $allowed_trafic = 'false') {
        return 403;
    }
}

Example if the deny list resides in the ./nginx.conf:

include /etc/nginx/conf.d/*.conf;

Example of my_deny_nginx_geo.conf:

geo $remote_addr $allowed_trafic {
    default true;
    1.4.32.0/19 false;
}

How to convert the data feed to a deny list for the Nginx geo module?

To create my_deny_nginx_geo.conf:

  • Download the data feed in CIDR notation to your server;
  • Use the following bash script:
zcat geoipify_ofac_cidr_2023_01_23.txt.gz > geoipify_ofac_cidr_2023_01_23_uncompressed.txt
while IFS= read -r line; do echo "${line} false;"; done < geoipify_ofac_cidr_2023_01_23_uncompressed.txt > my_deny_nginx_geo.conf.tmp
echo "geo \$remote_addr \$allowed_trafic {" > my_deny_nginx_geo.conf
echo "default true;" >> my_deny_nginx_geo.conf
cat my_deny_nginx_geo.conf.tmp >> my_deny_nginx_geo.conf
echo -n "}" >> my_deny_nginx_geo.conf
rm -f my_deny_nginx_geo.conf.tmp
rm -f geoipify_ofac_cidr_2023_01_23_uncompressed.txt

How to use data feeds with an Apache web server?

Enable the rewrite module with the a2enmod rewrite command. Example of ./mySite.conf if the deny list does not reside in the default config folder:

<VirtualHost *:80>
    ServerName mysite.localhost.local
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    Alias /blocked "/var/www/blocked"
    <Directory "/var/www/blocked">
        AllowOverride All
        Require all granted
    </Directory>
    <IfModule mod_dir.c>
        DirectoryIndex index.php
    </IfModule>
    <Location /blocked>
        <RequireAll>
            Require all granted
            Include /etc/apache2/my_deny_apache2.conf
        </RequireAll> ErrorDocument 403 "<h3>Your IP is blocked.</h3>"
    </Location>
</VirtualHost>

Example of my_deny_apache2.conf:

Require not ip 1.0.1.0/24
Require not ip 1.0.2.0/23
Require not ip 1.0.4.0/32
Require not ip 1.0.8.0/21
Require not ip 1.0.16.0/32
Require not ip 1.0.32.0/19
Require not ip 1.0.64.0/32

How to convert the data feed to a deny list for Apache?

To create my_deny_apache2.conf:

  • Download the data feed in CIDR notation to your server;
  • Use the following bash script:
zcat geoipify_ofac_cidr_2023_01_23.txt.gz > geoipify_ofac_cidr_2023_01_23_uncompressed.txt
while IFS= read -r line; do echo "Require not ip ${line}"; done < geoipify_ofac_cidr_2023_01_23_uncompressed.txt > my_deny_apache2.conf
rm -f geoipify_ofac_cidr_2023_01_23_uncompressed.txt
Try our WhoisXML API for free
Get started