Ajouter la GeoIP à Nginx Proxy Manager 2/2

Ajouter la GeoIP à Nginx Proxy Manager 2/2

Lors du premier article, nous avons compilé et chargé les modules GeoIP dans Nginx Proxy Manager et nous avons téléchargé les bases de données GeoLite2 de Maxmind.

Ajouter la GeoIP à Nginx Proxy Manager 1/2
En complément de la mise en place de Nginx Proxy Manager pour gérer vos redirections de sous-domaines vers les services que vous hébergez, nous allons voir comment ajouter les informations GeoIP à NPM, nous permettant de bloquer les visiteurs venant de certains pays et/ou de loguer la provenance de

Nous pouvons maintenant configurer NPM pour utiliser tout ça, afin de bloquer et/ou loguer en se servant des informations GeoIP. Pour cela, nous allons ajouter des fichiers de configuration "custom".

Utilisation de la base de données

Pour charger la base de donnée voulue et définir des variables contenant les informations qui nous intéressent, nous allons créer un fichier http_top.conf dans le dossier prévu par NPM pour les configurations avancées, à savoir /dockers/nginx-proxym/data/nginx/custom.

charset utf-8;
geoip2 /data/geoip2/GeoLite2-City.mmdb {
	auto_reload 3h;
	$geoip2_metadata_country_build metadata build_epoch;
	$geoip2_data_country_code default=XX source=$remote_addr country iso_code;
	$geoip2_data_country_name default=- country names fr;
	$geoip2_data_city_name default=- city names fr;
	$geoip2_data_region_name default=- subdivisions 0 names fr;
}
http_top.conf

Cette configuration va permettre de charger le fichier GeoLite2-City.mmdb précédemment téléchargé et d'extraire dans des variables le code pays, le nom du pays, le nom de la ville et le nom de la région en français.
Pour ne pas avoir de problèmes avec les noms accentués, on définit le charset en UTF8.

Définition des IPs à bloquer suivant la provenance

Pour bloquer les IPs en provenance de certains pays, vous pouvez opter pour deux approches :

  • Bloquer tous les pays et n'en autoriser que certains, en ajoutant les lignes suivantes au fichier http_top.conf :
geo $allowed_ip {
	default no;             # On interdit par défaut
	192.168.1.0/24 yes;     # On autorise le réseau local
}

map $geoip2_data_country_code $allowed_country {
	default $allowed_ip;
	FR yes;                 # On autorise les IP Française
	BE yes;                 # On autorise les IP Belges
}
  • Autoriser tous les pays et ne bloquer que certains, en ajoutant les lignes suivantes au fichier http_top.conf :
geo $allowed_ip {
		default yes;             # On autorise par défaut
		192.168.1.0/24 yes;      # On autorise le réseau local
}

map $geoip2_data_country_code $allowed_country {
		default $allowed_ip;
		CN no;                 # On interdit les IP Chinoises
		RU no;                 # On interdit les IP Russes
}
Info ! Pour trouver le code pays sur deux lettres (ISO-3166-1), vous pouvez utiliser cette liste : https://en.wikipedia.org/wiki/ISO_3166-1#Officially_assigned_code_elements

Mise en place du blocage

Une fois que nous avons défini ce qu'on veut bloquer/autoriser, il ne reste plus qu'à le rendre effectif.
Il faut pour cela ajouter ces lignes dans un fichier de configuration :

if ($allowed_country = no) {
	return 444;
}

Le fichier dans lequel ajouter ces lignes dépend du niveau où l'on veut effectuer le blocage :

  • Blocage Général : Il faut créer un fichier server_proxy.conf avec ce contenu dans le dossier /dockers/nginx-proxym/data/nginx/custom
  • Blocage au niveau de chaque Proxy Host : Il faut ajouter ce contenu dans la configuration avancée (Custom Nginx Configuration) de chaque hôte (Interface web de NPM).
Info ! En définissant plusieurs listes $allowed_ip et $allowed_country, il est possible d'avoir des blocages différents suivant les Proxy Hosts.

Création de logs avec les infos GeoIP

Pour l'instant, il n'est pas possible dans NPM de modifier le format de log par défaut, nous allons donc devoir créer un autre fichier de log contenant les infos GeoIP en plus.
Pour cela, ajoutons un nouveau format de log dans le fichier http_top.conf :

log_format proxy_geo escape=json '[$time_local] [Client $remote_addr] [$allowed_country $geoip2_data_country_code $geoip2_data_country_name $geoip2_data_region_name $geoip2_data_city_name] "$http_user_agent" '
                                 '$upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_referer"';

Les informations loguées par NPM sont les même que celles par défaut, on y a juste ajouté les infos GeoIP : [$allowed_country $geoip2_data_country_code $geoip2_data_country_name $geoip2_data_region_name $geoip2_data_city_name], à savoir, si la requête est autorisée ou non, le code pays sur deux lettres, le nom du pays, le nom de la région et le nom de la ville.

Puis ajoutons dans la configuration avancée (Custom Nginx Configuration) de chaque hôte (Interface web de NPM), le code suivant qui génèrera le fichier de log au bon format à chaque requête sur cet hôte :

access_log /data/logs/proxy-host-%HOSTID%_access-geo.log proxy_geo;

En remplaçant %HOSTID% par l'id du proxy host que vous êtes en train de modifier.

On recharge la configuration de nginx avec la commande docker exec -it nginx-proxym nginx -s reload.

Et voilà, il n'y a plus qu'à tester la connexion aux hôtes avec un vpn, pour venir de différents pays/villes et voir si le blocage éventuel est bien effectif.

Vous pouvez voir le nouveau fichier de log en direct en utilisant la commande tail -f /dockers/nginx-proxym/data/logs/proxy-host-%HOSTID%_access-geo.log.

Exemples :

/dockers/nginx-proxym/data/logs# tail -f proxy-host-1_access-geo.log
[15/Dec/2021:14:24:58 +0000] [Client 192.168.1.51] [yes XX - - -] "Uptime-Kuma/1.11.1"  200 200 - GET https mon-hote.tld "/login" [Length 9708] [Gzip ] [Sent-to 192.168.1.69] ""
[15/Dec/2021:14:27:01 +0000] [Client 185.189.113.45] [yes FR France Île-de-France Paris] "Mozilla/5.0 (Linux; Android 10; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36"  302 302 - GET https mon-hote.tld "/" [Length 0] [Gzip ] [Sent-to 192.168.1.69] ""
[15/Dec/2021:14:27:47 +0000] [Client 89.40.182.9] [no IT Italie Lombardie Milan] "Mozilla/5.0 (Linux; Android 10; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36"   444 - GET https mon-hote.tld "/login" [Length 0] [Gzip ] [Sent-to 192.168.1.69] ""

La première ligne est une connexion provenant du réseau local, la deuxième provenant d'un serveur vpn à Paris, la troisième provenant d'un serveur vpn à Milan. On voit bien que les deux premières ont été acceptées et la troisième rejetée.


Conclusion

Le log de ces informations peut servir à faire des stats sur la provenance de vos visiteurs. Nous verrons dans un autre article comment exploiter ces informations. Quand au blocage par pays, il peut aider à sécuriser vos services web en bloquant les connexions venant de pays reconnus comme origine d'un gros pourcentage des attaques mondiales.

Bien qu'un peu technique, j'espère que cet article vous permettra de mettre en place de manière effective la GeoIP sur votre Nginx Proxy Manager en attendant que les modules soient intégrés dans l'image officielle.

Si vous avez des questions ou simplement souhaitez échanger avec nous, n'hésitez pas à laisser des commentaires ou à venir sur notre groupe Telegram.