geospatial Nginx

NGINX: Block Based on Geographical Location

Nginx is a high performance, lightweight, open source web server available to public for free of charge. It has tremendous number of valuable features compared to other lightweight servers. One of such features is its geoip_module, which is used to identify the geo graphical location from where the visitor comes. By default, it uses in combination with data provided by maxmind to find out the geographical location of the visitor. The advantage of identifying the geographical location is to enforce different policies to different geographical locations, for instance if a business is only available to countries in north America, with geoip_module it can block out all other visitors coming from other regions. This ensures the business doesn’t have to comply to rules, and regulations enforced by different regions, such as GDPR (General Data Protection Regulation).

Implementation

Even though there are many ways to implement the solution in the system, this guide demonstrates the easiest way to enroll it with minimum effort.

  1. Obviously, Nginx has to be installed in the system prior to initiate the steps in this guide. However, having Nginx installed is not enough, as it also requires geo_ip_module to be installed too. Maxmind used to release their database in dat format, but since a while ago it’s released in mmdb format. This makes Nginx to require a new geo_ip_module called ngx_http_geoip2_module. However, it’s not required as the old dat database is still sufficient. Anyway, if nginx isn’t installed set it up with the following two commands.
apt-get update
apt-get install nginx
  1. Type the following command to make sure http_geoip module is installed.
nginx -V

  1. There are multiple ways to acquire/build the database that contains IP addresses, and their respective country, city names. Install the geo_ip database with the following commands. Using this method makes it easy to install the geo_Ip database in the system. However, the most ideal way is downloading a fresh copy as they are updated with latest information. So, use one of the three options given below. The first option is enough for any average user, the 2nd option is to get the latest database of maxmind, the third option converts the mmdb database to its respective dat file format.
     
    It’s time, and resource consuming, and thus not recommended for weak servers. However, if updated database is still needed, then use the option 2. It saves the time, and money in converting the file, but the security can’t be guaranteed as it’s converted by someone else, not by any official party. The option 3 requires 3 pip packages, setuptools, ipaddr, dcryptit. And it uses python 2 to process the script. The last line converts the zip archive to .dat file. Even though it’s mentioned about conversion of mmdb file format to .dat, here it actually does convert a CSV file to a .dat file format, and thus it requires geoname2fips.csv file which comes along with the conversion file bundle.

Option 1

apt-get install geoip-database libgeoip1

Option 2

cd /usr/share/GeoIP
wget -o maxmind.dat.gz https://bit.ly/2Gh3gTZ
gunzip maxmind.dat.gz

Option 3

cd /home/
mkdir geolite2legacy/
git clone https://github.com/sherpya/geolite2legacy
apt-get install python
apt-get install python-pip
pip install setuptools
pip install ipaddr
pip install dcryptit
cd /usr/share/
mkdir GeoIP/
cd /usr/share/GeoIP/
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
pyton /home/geolite2legacy/geolite2legacy.py -i /usr/share/GeoIP/GeoLite2-Country-CSV.zip -f
/home/geolite2legacy/geoname2fips.csv -o /usr/share/GeoIP/GeoLite2-Country.dat
  1. Configure the Nginx configuration file as following. Type the command in the first line in Linux terminal as usual, and copy the rest of the lines to the nginx.conf file. Make sure the name mentioned in /usr/share/GeoIP/GeoIP.dat matches with the dat file stored in usr/share/GeoIP folder. Even though in the following example, it specifies just one country, multiple country codes can be specified as the given example with one line per country code. The available country code list for countries can be located at this location. http://www.maxmind.com/app/iso3166.
nano /etc/nginx/nginx.conf
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default yes;
LK no;
}
  1. Open the default file via any text editor (nano is preferred as it’s quite easy to edit with it), then add the content since 2nd line to in between anywhere in location block in the default file. The code works as this, when a visitor makes a request to the web server, nginx fetches their IP addresses and matches with its records to find the respective country code, if the country mentioned in the map block matches, the no is assigned to the $allowed_country variable, and thereby checking the $allowed_country allows to manipulate the response. In this guide it uses no, and thus the visitor is denied from seeing the content. If there are multiple domains like .com, .lk, or nucuta.com, or nucuta.net add the code since line 3 to each “domain”.conf file as well. If nginx is configured well, the file to respective domain is located in sites-available folder.
nano /etc/nginx/sites-available/default
if ($allowed_country = no) {
return 444;
}
  1. Restart the nginx server with the following command. Hereafter accessing the web server from any sri lankan (LK) domain causes the web server to return nothing as seen in the following screenshots. 444 in nginx represents nothing. Any other code such as 302, 301, 404 can be used here instead as well. If 302,301 are specified, an URL to redirect the visitor should be specified as well.
systemctl restart nginx

Conclusion

Blocking visitors based on their geography is critical for some businesses to function due to various regional rules, and regulations. Nginx caters to such needs with its geo_ip module. It uses maxmind databases to find the country by the ip address of the visitor. The database works with both Ipv4, and ipv6. Since maxmind discontinued their legacy dat database format, the only way to make use of their data is either converting the new file format to dat file or using an already converted one or use a third party module for Nginx to support mmdb file format. The python script provides here is ideal for conversion even though it takes a while to see the outcome. Maxmind guarantees over 99% accuracy in finding the country based on the IP; hence it’s a must have tool for any business.

About the author

Nucuta

Nucuta

NUCUTA is a technology blog where various topics about computer hardware, software, mobile phones, gadgets and many other are covered, including but not limited to tutorials, reviews, and topics in business management, finance, accounting, self improvement and technology news.