Compile GeoIP2 in OpenResty and how to use it

After the basic guide about how to prepare your system to compile modules (which you can find here), is time to learn how to compile the GeoIP2 module in OpenResty. We will start with this module which is relatively easy to compile. I’m using Debian by default, so all described steps in this guide are done on Debian 10.

I suppose that you have ended here because you know what GeoIP module is. If not, Is a module that allow you to get the geolocalization of an IP address. This will allow you to know from where the users are, and block countries from where you don’t want to receive traffic. The database includes more info, like city, postal code… and also have a Premium version which is more accurate but here I’ll talk about the free version.

Well, the first that you have to do is to prepare your system to compile the module. I recommend to have a virtual machine to avoid to fill your system of packages. To do it, you can use the link in the first paragraph that will open the guide in a new window.

Once the server is prepared, create a temporary folder to store the workspace. Here I will create the /tmp/compile folder, but take care if your tmp folder size is limited:

mkdir /tmp/compile && cd /tmp/compile

Once there, we will download the source code from the OpenResty webpage. Is important to download the same version that we have installed, so we will use the following commands to do it:

wget https://openresty.org/download/openresty-$(openresty -v 2>&1|cut -d "/" -f2).tar.gz
tar xvf openresty-$(openresty -v 2>&1|cut -d "/" -f2).tar.gz

Now that we have the source code extracted, we have to download the GeoIP2 module source code. You can do it directly from their repository, which is located in this link. In this guide we will use git to clone the repository, so you need to create a modules folder and then clone the repository here:

mkdir /tmp/compile/openresty-$(openresty -v 2>&1|cut -d "/" -f2)/modules
cd /tmp/compile/openresty-$(openresty -v 2>&1|cut -d "/" -f2)/modules
git clone https://github.com/leev/ngx_http_geoip2_module.git

Once the repository is cloned we will see a folder called ngx_http_geoip2_module inside the modules folder, with the GeoIP2 source code. Now we have to install the basic GeoIP2 requirements, for which we can use this command:

apt-get install libmaxminddb0 libmaxminddb-dev

Once installed, navigate to the folder where the Nginx source code is, which is inside the bundle folder, and run the compilation commands:

# Go to the Nginx source code folder
cd ../bundle/nginx-$(openresty -v 2>&1|cut -d "/" -f2|grep -oP '^d+.d+.d+')

# Environment variables required for the compilation (otherwise will fail)
export LUAJIT_LIB="/usr/local/openresty/luajit/lib/"
export LUAJIT_INC="../LuaJIT-*/src/"

# Get the installed OpenResty compilation options to avoid
# the "binary not compatible" error
COMPILEOPTIONS=$(openresty -V 2>&1|grep -i "arguments"|cut -d ":" -f2-)

# Configure the compilation with those options
# adding GeoIP2 as dinamic module
eval ./configure $COMPILEOPTIONS --add-dynamic-module=../../modules/ngx_http_geoip2_module

# Compile just the module
make modules

Now that we have the module compiled, we will see it inside the obj folder with the ngx_stream_geoip2_module.so name:

ls -la objs/ngx_stream_geoip2_module.so

Using the GeoIP2 module in OpenResty

Copy and activate

Now that we have the module ready, we can start to use it on OpenResty. This module is very simple, but useful, and allow us to block countries, hace stadistics about from where our clients are, redirect to a different domain by country…

To use it, first we hace to copy it to OpenResty folder. First we will create the modules folder if doesn’t exists:

mkdir /usr/local/openresty/nginx/modules/

Then if we still on compilation folder, we will use the following command to copy the module:

cp obj/ngx_stream_geoip2_module.so /usr/local/openresty/nginx/modules/

Finaly we will add the following line to tell to Nginx tha must load the module. The configuration file is located on /usr/local/openresty/nginx/conf/nginx.conf:

load_module modules/ngx_http_geoip2_module.so;

This line must be placed at the begin of the configuration file or will fail. For now will not be usefull because we don’t have a database to get the country. In the next section you will see how to download that database.

Download the GeoIP2 DB file

Now that the module is compiled an installed, we need to download the database to use it. To do it we need to go to MaxMind page and register (now is required):

https://dev.maxmind.com/geoip/geoip2/geolite2/

I recommend to download the GeoIP Country database, which is more lightweight and enought for the most requirements. Also we can yse the GeoIP City database if we need more data about our clients.

Once we have downloaded the database, we need to extract the files and copy the mmdb file to a folder where is accesible by OpenResty. I have decided to use this folder to keep all together:

/usr/local/openresty/nginx/maxmind/

Configure OpenResty

Now that we have the database, we need to tell to the module where is and which data we want to extract for every user. To do it we will open the configuration file again (/usr/local/openresty/nginx/conf/nginx.conf), and we will add the following lines inside the http block:

geoip2 /usr/local/openresty/nginx/maxmind/maxmind-country.mmdb {
    auto_reload 5m;
    $geoip2_metadata_country_build metadata build_epoch;
    $geoip2_data_country_code default=US source=$remote_addr country iso_code;
    $geoip2_data_country_name country names en;
}

This lines will configure the follwing:

  • Reload the file every 5 minutes to keep it up to date without reload the server. Usefull if you use any script to download the database updates.
  • Save the country code in two letters format (iso3166) inside the geoip2_data_country_code variable. If the IP country is unknown, US will be used by default.
    More info: https://dev.maxmind.com/geoip/legacy/codes/iso3166/
  • Inside the $geoip2_data_country_name we will get the full country name in the language that we have set at the end (“en” in the example). We have the following languages:
    • de: German
    • en: English
    • es: Spanish
    • fr: French
    • ja: Japonese
    • pt-BR: Brazilian Portuguese
    • ru: Russian
    • zh-CN: Chinese

Now we can use thos variables for whatever we want. There are more data on the database which we can use. You will find more info in the MaxMind webpage.

As always, I hope that this guide has been useful, and don’t forget to leave any comment and share if liked you.

¡Greetings!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.