NGINX: Module « geoip2 » pour Debian

Le module geoip pour nginx a besoin de base de données à jour pour être pertinent.
Ces bases peuvent être téléchargé gratuitement, mais leur format a changé récemment, les rendant incompatible avec le module geoip historique.
C’est là qu’arrive le module geoip2 qui peut lire ce nouveau format, mais hélas, le module pour nginx est actuellement introuvable pour Debian.

Les sources du module geoip2 sont par là:
https://github.com/leev/ngx_http_geoip2_module
… mais pour qu’il puisse être dynamiquement importé par la version nginx de Debian, il faut recompiler entièrement le package nginx.

Comme vous allez le voir, au final, on ne récupérera que le module ngx_http_geoip2_module.so qui nous intéresse.

Et pour les plus pressé, le module prêt à l’emploi:

ATTENTION: ce module dépend de la librairie libmaxminddb qui se trouve dans le package Debian nommé libmaxminddb0 .

… et voici une méthode pour générer ce module.

Préparer la recompilation de « nginx »

Sources:

Ce mettre dans un dossier qui va bien pour compiler, par exemple /usr/local/src/ dans lequel on créé un dossier nginx.
On y importe les sources:

$ apt-get source nginx/stable

(Dans mon cas, un dossier nommé nginx-1.10.3 est apparu…)
On charge les dépendances nécessaires:

$ su -
# apt-get build-dep nginx/stable

Préparer les sources du module « geoip2 »

A ce stade, on est prêt a recompiler nginx , mais nous devons d’abord faire quelques modifications pour inclure notre module geoip2.
Choisir un dossier, par exemple /usr/local/src/geoip2 dans lequel on exécute la commande git suivante:

# git clone https://github.com/leev/ngx_http_geoip2_module.git

… et un dossier ngx_http_geoip2_module apparaît.

On installe aussi une librairie dont dépend le module:

# apt-get install libmaxminddb-dev

Recompiler avec les sources de « geoip2 »

Retour dans le dossier où sont les sources de nginx (pour moi dans /usr/local/src/nginx/nginx-1.10.3/ ) .
On doit éditer le fichier debian/rules afin d’inclure la compilation du module geoip2.

Pour cela, j’ai ajouter une ligne --add-dynamic-module=<chemin_source_module> à la toute fin de la déclaration de extras_configure_flags , soit (exemple):

... <snip> ...

extras_configure_flags := \
    $(common_configure_flags) \
    --with-http_addition_module \
... <snip> ...
    --add-dynamic-module=$(MODULESDIR)/nginx-upstream-fair \
    --add-dynamic-module=$(MODULESDIR)/ngx_http_substitutions_filter_module \
    --add-dynamic-module=/usr/local/src/geoip2/ngx_http_geoip2_module

... <snip> ...

… et c’est tout pour les modifications 🙂 .

(Notez le \ à la toute fin de la ligne précédente. )
Et maintenant, on se repositionne à la base des sources (dans nginx-1.10.3) et on compile:

$ debuild -i -us -uc -b

A la fin, on se retrouve avec des tas fichiers « .deb » du résultat de la compilation.

Mais ce qui nous importe ici, c’est le module geoip2 compilé « à la Debian » , qu’on trouve là:
debian/build-extras/objs/ngx_http_geoip2_module.so

Avant de le distribuer et de l’utiliser, on sera avisé de retirer les informations de debug sans intérêt ici:

$ strip ngx_http_geoip2_module.so

Voila, notre module est maintenant prêt a être utiliser par nginx .

Configuration de « geoip2 »

On va maintenant utiliser ce nouveau module sur un serveur avec un service nginx déjà opérationnel.
Nous l’avons vu à la compilation, ce module dépend de la librairie libmaxminddb , donc il faut d’abord l’installer:

# apt-get install libmaxminddb0

On télécharge la base GeoLite2-Country.mmdb , qui suffira pour notre exemple, et on la place dans (exemple):
/var/local/geoip2/

Pour notre module, par exemple toujours, on le dépose dans un dossier /etc/nginx/modules-extras qu’on aura préalablement créé.

Notre exemple sera simple, puisqu’il va montrer comment interdire l’accès a un site depuis certains pays.

Dans nginx.conf (extrait) :

load_module /etc/nginx/modules-extras/ngx_http_geoip2_module.so;

http {
    ... <snip> ...

    geoip2 /var/local/geoip2/GeoLite2-Country.mmdb {
        $geoip2_data_country_code default=US source=$remote_addr country iso_code;
    }

    ... <snip> ...
}

et puis un exemple de configuration pour un site quelconque:

map $geoip2_data_country_code $denied_country {
    default       0;
    RU            OK;
    CN            OK;
    US            OK;
}

server {

    ... <snip> ...

    if ( $denied_country = OK ) {
        return 403;
    }

    ... <snip> ...

}

Vérifions la configuration :

# nginx -t
# systemctl reload nginx

Voila.