GeoIP lookups with Nginx

David E Lares S
2 min readMar 26, 2024

Assuming you already had a fresh installation of a Linux OS and the Nginx server (if not, check this post), we can perform server-side validation based on the geography of the request made to the server.

This is an “archaic” way to achieve it, still valid, but, you can have way more robust solutions for this. My intention is not to make an in-depth revisit of Nginx but to have at least a certain experience with the tool.

This whole GeoIP can be achieved with the help of a bundled module called http_geoip_module and the MaxMind database.

Here’s the integration in simple steps:

  1. Before starting, we need a pretty important pre-requisite, the libgeoip-dev package. It’s installed like this: apt-get install libgeoip-dev
  2. Then, you’ll need to build your Nginx configuration script by adding the --with-http_geoip_module
  3. Check your installation and restart the service: systemctl restart nginx

At this point, we should have the module ready to be used, but we need data to evaluate. And that’s what MaxMind is required.

MaxMind is a GeoIP service that provides geo-related databases and also offers a Transaction Risk API to prevent fraud, it’s an awesome tool IMO, but moving on, we need a database for query and match IP locations.

  1. To use the GeoIP module we need to create a directory for it, I created the /etc/nginx/geoip
  2. Download the files, and “unzip” them with gunzip like this:
wget [URL of the service]/GeoIP.dat.gz
gunzip -f GeoIP.dat.gz

You can download the city files as well

As a note: the URL changes in time, but you can find more information here.

So, next, we need to integrate them with Nginx, and for this, we can add both .dat files in the Nginx’s http module:

http {
geoip_country /etc/nginx/geoip/geoIp.dat;
geoip_city /etc/nginx/geoip/getoLiteCity.dat;
location / {
return 200 "Visiting from: $geo_country_name";
}
}

Both geoip_country and geoip_city functions are available from the http_geoip_module and are assigned the exact location of the databases. So, once the setup is successful, you can access the country name using the $geo_country_name variable.

With this feature, you can work every function available in the ngx_http_geoip_module module, just to perform direct validation in the location block, it's up to you and what you are trying to achieve. For more in-depth functionality, refer to the module documentation here.

This is a very straightforward way of achieving geo control of your service, of course, the MaxMind databases change periodically, so it is recommended to subscribe to a monthly or full-year plan to get the most recent data available.

This is an overwhelming feature that scares a lot of people, but once you get it, you see it can’t be easier.

Happy geolocating :)

--

--