2026年11月12日
2026年11月12日
Restreindre l’accès par pays avec Nginx GeoIP2 (GeoLite2, WordPress)
Cet article est une édition localisée de l'original japonais. Lire l'original en japonais
Pour restreindre l'accès par pays avec Nginx, la méthode actuelle (novembre 2026) consiste à utiliser le module GeoIP2 (ngx_http_geoip2_module) avec la base GeoLite2 de MaxMind, à stocker le code pays dans une variable via un bloc geoip2, puis à décider d'autoriser ou de refuser avec map. L'ancienne procédure des tutoriels, qui consiste à télécharger un fichier .dat GeoLite avec wget, ne fonctionne plus, car la distribution de ces données a pris fin.
Voici d'abord l'essentiel.
- L'ancien module
ngx_http_geoip_module(GeoIP Legacy) ne convient plus pour une nouvelle installation, car MaxMind ne distribue plus l'ancien format de données. Passez à GeoIP2 (format.mmdb). - GeoLite2 est gratuit, mais il faut un compte MaxMind et une clé de licence ; le téléchargement et la mise à jour se font avec
geoipupdate. - Côté Nginx, un bloc
geoip2crée une variable comme$geoip2_country_code,mapla convertit en 0 / 1 (l'équivalent deallow/deny), et unelocationrenvoiereturn 403. - Si le site passe par un CDN comme Cloudflare, il faut d'abord restaurer l'IP réelle du visiteur avec
real_ip_header; sinon tous les accès sont attribués au pays du CDN. - La restriction par pays est une aide pour réduire les attaques : un VPN ou un relais permet de la contourner. Il est plus réaliste de l'appliquer à la page de connexion et à l'administration plutôt qu'à l'ensemble des pages publiques.
Différences entre l’ancien geoip et GeoIP2
| Critère | ngx_http_geoip_module (ancien) | ngx_http_geoip2_module (GeoIP2) |
|---|---|---|
| Format des données | GeoIP Legacy (.dat) |
GeoIP2 (.mmdb) |
| Données gratuites | Terminé (distribution arrêtée en 2019) | GeoLite2 (compte et clé de licence requis) |
| Bibliothèque requise | libGeoIP | libmaxminddb |
| Obtention du module | Inclus dans Nginx (--with-http_geoip_module) |
Module tiers leev/ngx_http_geoip2_module. Paquet disponible sous Debian / Ubuntu |
| Variables | Fixes, comme $geoip_country_code |
Vous les nommez vous-même dans le bloc geoip2 |
Si votre configuration actuelle utilise geoip_country, la base n'est plus mise à jour et la détection est donc périmée. Profitez-en pour passer à GeoIP2.
Étape 1 : s’inscrire chez MaxMind et créer la clé de licence
- Créez un compte gratuit depuis la page GeoLite2 de MaxMind.
- Après connexion, générez une License Key dans l'espace de gestion du compte (la clé n'est affichée qu'au moment de sa création : notez-la).
- Pour la base à utiliser,
GeoLite2-Countrysuffit si vous n'avez besoin que du pays, etGeoLite2-Citysi vous voulez aller jusqu'à la ville. Pour une restriction par pays, Country convient.
Les conditions d'utilisation (GeoLite2 End User License Agreement) contiennent des règles sur la redistribution et l'affichage des données. Un usage limité à la détection sur vos propres serveurs reste normalement dans le cadre, mais vérifiez les conditions lors de l'inscription.
Étape 2 : récupérer et mettre à jour la base avec geoipupdate
GeoLite2 est mise à jour régulièrement : n'allez pas la télécharger à la main, utilisez geoipupdate (documentation de geoipupdate).
# Debian / Ubuntu
sudo apt install geoipupdate
# Famille RHEL (AlmaLinux / Rocky Linux) : depuis EPEL
sudo dnf install geoipupdate
Renseignez l'identifiant de compte et la clé de licence dans le fichier de configuration /etc/GeoIP.conf.
AccountID 123456
LicenseKey votre_clé_de_licence
EditionIDs GeoLite2-Country
# Dossier de stockage : valeur par défaut de la distribution (/var/lib/GeoIP sous Debian / Ubuntu, souvent /usr/share/GeoIP ailleurs).
# Pour le changer : DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/ # succès si GeoLite2-Country.mmdb est présent
Le paquet geoipupdate de la distribution inclut en général une exécution périodique via un timer systemd ou cron (vérifiez avec systemctl list-timers | grep geoip). Sinon, ajoutez une tâche cron environ une fois par semaine.
Étape 3 : installer le module GeoIP2 dans Nginx
Debian / Ubuntu (Nginx installé avec apt)
sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/ # 50-mod-http-geoip2.conf y est placé
nginx -t
Nginx du paquet nginx.org ou compilé depuis les sources
Après avoir installé libmaxminddb, compilez un module dynamique à partir des sources de la même version que le Nginx en cours d'exécution.
sudo apt install libmaxminddb-dev # famille RHEL : libmaxminddb-devel
cd /usr/local/src
git clone https://github.com/leev/ngx_http_geoip2_module
curl -LO https://nginx.org/download/nginx-1.26.3.tar.gz # adaptez la version à celle indiquée par nginx -v
tar xzf nginx-1.26.3.tar.gz && cd nginx-1.26.3
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
make modules
sudo cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/
Chargez-le en tête de nginx.conf (avec les paquets de la distribution, c'est fait automatiquement).
load_module modules/ngx_http_geoip2_module.so;
Étape 4 : stocker le code pays dans une variable et décider d’autoriser ou de refuser
À placer dans le bloc http. Le bloc geoip2 met le code pays dans une variable, puis map donne 1 aux pays autorisés et 0 à tous les autres.
http {
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_country_code country iso_code;
}
# Pays autorisés pour l'administration (code à 2 lettres ISO 3166-1)
map $geoip2_country_code $admin_allowed {
default 0;
JP 1;
"" 1; # Non déterminé (IP privée, etc.) : autorisé. Mettez 0 pour refuser
}
}
auto_reload est l'intervalle auquel Nginx relit, sans redémarrage, la base remplacée par geoipupdate.
Étape 5 : restreindre uniquement la page de connexion et l’administration de WordPress
Voici un exemple qui laisse les pages publiques libres et ne filtre par pays que wp-login.php et /wp-admin/. Placez-le dans le bloc server.
server {
# ... configuration existante ...
location = /wp-login.php {
if ($admin_allowed = 0) { return 403; }
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ^~ /wp-admin/ {
if ($admin_allowed = 0) { return 403; }
# Si une extension externe utilise admin-ajax.php, l'autoriser dans une location distincte
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
}
La combinaison de if et de return est une forme que Nginx gère sans risque. /wp-admin/admin-ajax.php peut être appelé sans connexion par des fonctions des pages publiques (formulaires, défilement infini, etc.) ; décidez donc de l'exclure ou non de la restriction selon les fonctions de votre site.
Application et vérification :
sudo nginx -t && sudo systemctl reload nginx
# Depuis votre pays : 200 ou 302 attendu
curl -sI https://example.com/wp-login.php | head -1
# Vérification de la détection (exemple : écrire le code pays dans les logs)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';
Pour vérifier le comportement depuis l'étranger, accédez à wp-login.php via un VPN situé à l'étranger ou un service de supervision hors du pays, et vérifiez que vous obtenez bien un 403.
Derrière un CDN (Cloudflare, etc.)
Derrière un CDN, $remote_addr correspond à l'IP du CDN, et tous les visiteurs sont donc attribués au pays du CDN. Commencez par restaurer l'IP réelle du visiteur avec ngx_http_realip_module (module realip).
# Exemple avec Cloudflare. Mettez la liste à jour régulièrement d'après les IP Ranges officielles de Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... lister toutes les plages Cloudflare ...
real_ip_header CF-Connecting-IP;
geoip2 examine par défaut $remote_addr ; la détection porte donc sur l'IP réelle après remplacement par realip. Cloudflare propose lui-même un contrôle d'accès par pays (règles personnalisées du WAF) : si vous utilisez Cloudflare, il est plus simple de restreindre de ce côté plutôt qu'avec Nginx. Consultez aussi Configurer Cloudflare avec WordPress.
Limites de la restriction par pays
- La détection GeoIP est une estimation fondée sur les informations d'enregistrement des adresses IP : un VPN, un proxy ou un relais depuis un cloud étranger permettent de la contourner.
- Sur les réseaux mobiles ou d'entreprise, une IP peut être attribuée à un autre pays que la localisation réelle. Cela pose aussi un problème d'exploitation, par exemple un administrateur en déplacement à l'étranger qui se retrouve bloqué.
- La restriction par pays sert donc d'appoint pour réduire les tentatives de connexion par force brute, en complément de l'authentification à deux facteurs, de la limitation des tentatives de connexion et de la protection de wp-admin par authentification Basic.
Questions fréquentes
Quelle est la différence entre les modules geoip et geoip2 de Nginx ?
L'ancien module geoip lit des données au format GeoIP Legacy (.dat), dont MaxMind a arrêté la distribution. Le module geoip2 (ngx_http_geoip2_module) lit le format actuel .mmdb et permet d'utiliser les données gratuites GeoLite2. Pour toute nouvelle configuration, utilisez geoip2.
GeoLite2 est-il gratuit ? Faut-il s’inscrire ?
Il est gratuit, mais il faut un compte MaxMind et une clé de licence. Le téléchargement et la mise à jour périodique se font avec geoipupdate. L'ancienne méthode, qui télécharge directement sans clé, ne fonctionne plus.
Une restriction par pays empêche-t-elle les connexions frauduleuses à WordPress ?
Elle réduit les tentatives par force brute, mais on ne peut pas dire qu'elle les empêche, puisqu'un VPN ou un relais depuis un serveur étranger la contourne. Combinez-la avec la limitation des tentatives de connexion, l'authentification à deux facteurs, l'authentification Basic, etc.
Avec Cloudflare, tous les visiteurs apparaissent dans le même pays
C'est parce que, derrière un CDN, la source de la connexion est l'IP du CDN. Restaurez l'IP réelle avec set_real_ip_from et real_ip_header CF-Connecting-IP avant la détection. Il est aussi possible de restreindre par pays avec le WAF de Cloudflare.
Avec GeoLite2-City, peut-on restreindre jusqu’à la ville ?
Les codes de ville et de région peuvent aussi être placés dans des variables, mais la précision au niveau de la ville est inférieure à celle du pays, et les erreurs de détection risquent de bloquer des utilisateurs légitimes. Pour le contrôle d'accès, mieux vaut s'en tenir au niveau du pays.
Conclusion
- La restriction par pays de Nginx se fait aujourd'hui avec GeoIP2 (ngx_http_geoip2_module + GeoLite2
.mmdb), et les données sont mises à jour avecgeoipupdate. - Le bloc
geoip2place le code pays dans une variable,mapdécide d'autoriser ou de refuser, et leslocationdewp-login.phpet de/wp-admin/renvoientreturn 403. - Derrière un CDN, restaurez d'abord l'IP réelle ; utilisez la restriction par pays comme mesure d'appoint, avec l'authentification à deux facteurs et d'autres protections.
Articles associés
- Comment restreindre l'accès à l'API REST de WordPress
- Créer un mot de passe d'authentification Basic Apache avec htpasswd : protéger wp-admin
- Guide complet : configurer Cloudflare avec WordPress
Références : ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module
Historique des mises à jour : 2026-11-09 refonte complète (la procédure GeoLite obsolète, dont la distribution a pris fin, est remplacée par la procédure GeoIP2 et geoipupdate ; ajout d'un exemple de restriction de l'administration WordPress et d'une remarque sur les CDN). Cet article est publié par WordPress Hakase (Lightscend Co., Ltd.).
Une question sur WordPress ? L'éditeur de ce site est basé au Japon et répond en japonais. Contact (en japonais)