2026年11月12日

2026年11月12日

Nginx: toegang per land beperken met GeoIP2 (GeoLite2, WordPress-beheer)

Dit artikel is een gelokaliseerde versie van het Japanse origineel. Lees het Japanse origineel

Om in Nginx de toegang per land te beperken, gebruik je de GeoIP2-module (ngx_http_geoip2_module) met de GeoLite2-database van MaxMind: een geoip2-blok zet de landcode in een variabele en map bepaalt of je toelaat of weigert. Zo werkt het per november 2026. De werkwijze uit oude artikelen, een .dat-bestand van GeoLite ophalen met wget, werkt niet meer, want die data wordt niet meer verspreid.

Eerst de conclusie in het kort.

  • De oude ngx_http_geoip_module (GeoIP Legacy) kun je niet meer nieuw gebruiken, omdat MaxMind de oude dataformaten niet meer verspreidt. Stap over op GeoIP2 (formaat .mmdb).
  • GeoLite2 is gratis, maar je hebt een MaxMind-account en een licentiesleutel nodig. Downloaden en bijwerken doe je met geoipupdate.
  • In Nginx maak je met een geoip2-blok een variabele als $geoip2_country_code, bepaal je met map een 0 of 1 die overeenkomt met allow / deny, en geef je in een location return 403.
  • Zit je site achter een CDN zoals Cloudflare, herstel dan eerst met real_ip_header het echte IP-adres van de bezoeker. Anders wordt iedereen beoordeeld als bezoeker uit het land van de CDN.
  • Beperken per land helpt aanvallen te verminderen, maar je omzeilt het met een VPN of een tussenserver. Gebruik het daarom op de inlog- en beheerpagina's en niet op alle openbare pagina's.
Stappen voor de GeoIP2-configuratie van Nginx: registreren bij MaxMind, de database ophalen met geoipupdate, de module laden, beoordelen met geoip2 en map, beperken met location

Verschil tussen de oude geoip en GeoIP2

Onderdeel ngx_http_geoip_module (oud) ngx_http_geoip2_module (GeoIP2)
Dataformaat GeoIP Legacy (.dat) GeoIP2 (.mmdb)
Gratis data Gestopt (verspreiding beëindigd in 2019) GeoLite2 (account en licentiesleutel nodig)
Benodigde bibliotheek libGeoIP libmaxminddb
Module verkrijgen Standaard in Nginx (--with-http_geoip_module) Module van een derde partij, leev/ngx_http_geoip2_module. Voor Debian / Ubuntu bestaat een pakket
Variabelen Vaste namen zoals $geoip_country_code Je geeft zelf namen in het geoip2-blok

Gebruik je in je bestaande configuratie geoip_country, dan wordt de database niet meer bijgewerkt en is de beoordeling verouderd. Stap bij deze gelegenheid over op GeoIP2.

Stap 1: registreren bij MaxMind en een licentiesleutel maken

  1. Maak een gratis account aan via de GeoLite2-pagina van MaxMind.
  2. Maak na het inloggen in het accountbeheer een License Key aan (de sleutel wordt alleen bij het aanmaken getoond, dus bewaar hem).
  3. Als database kies je GeoLite2-Country als je alleen het land nodig hebt, of GeoLite2-City als je ook de stad wilt weten. Voor beperken per land volstaat Country.

De gebruiksvoorwaarden (GeoLite2 End User License Agreement) bevatten regels over het herdistribueren en tonen van de data. Gebruik je ze alleen op je eigen server om te beoordelen, dan valt dat gewoonlijk binnen het toegestane, maar lees de voorwaarden bij het registreren.

Stap 2: de database ophalen en bijwerken met geoipupdate

GeoLite2 wordt regelmatig bijgewerkt, dus download je het niet met de hand maar gebruik je geoipupdate (documentatie van geoipupdate).

# Debian / Ubuntu
sudo apt install geoipupdate

# RHEL-familie (AlmaLinux / Rocky Linux): via EPEL
sudo dnf install geoipupdate

Zet in het configuratiebestand /etc/GeoIP.conf je account-ID en licentiesleutel.

AccountID 123456
LicenseKey hier-je-uitgegeven-sleutel
EditionIDs GeoLite2-Country
# De opslaglocatie is de standaard van je distributie (Debian / Ubuntu: /var/lib/GeoIP, elders meestal /usr/share/GeoIP).
# Wil je die wijzigen, gebruik dan DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/   # Staat GeoLite2-Country.mmdb er, dan is het gelukt

Het pakket geoipupdate brengt meestal een instelling mee om het periodiek uit te voeren via een systemd-timer of cron (controleer met systemctl list-timers | grep geoip). Ontbreekt die, voeg dan een cron-taak toe die ongeveer eens per week draait.

Stap 3: de GeoIP2-module in Nginx installeren

Debian / Ubuntu (Nginx uit apt)

sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/   # 50-mod-http-geoip2.conf wordt hier geplaatst
nginx -t

Nginx uit de pakketten van nginx.org of zelf gebouwd

Installeer libmaxminddb en bouw daarna een dynamische module uit de broncode van dezelfde versie als de Nginx die draait.

sudo apt install libmaxminddb-dev   # RHEL-familie: 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   # Kies de versie die bij nginx -v past
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/

Laad de module bovenaan nginx.conf (bij pakketversies gebeurt dat automatisch).

load_module modules/ngx_http_geoip2_module.so;

Stap 4: de landcode in een variabele zetten en toestaan of weigeren

Dit schrijf je in het http-blok. Het geoip2-blok zet de landcode in een variabele, en map geeft de toegestane landen de waarde 1 en alle andere de waarde 0.

http {
    geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        auto_reload 60m;
        $geoip2_country_code country iso_code;
    }

    # Landen die het beheer mogen gebruiken (tweeletterige ISO 3166-1-code)
    map $geoip2_country_code $admin_allowed {
        default 0;
        JP      1;
        ""      1;   # Niet te bepalen (bijvoorbeeld privé-IP's): toegestaan. Wil je weigeren, zet dan 0
    }
}

auto_reload is het interval waarmee de database opnieuw wordt ingelezen nadat geoipupdate hem heeft vervangen, zonder herstart.

Stap 5: alleen de WordPress-login en het beheer beperken

Dit voorbeeld beperkt alleen wp-login.php en /wp-admin/ per land en laat de openbare pagina's ongemoeid. Zet het in het server-blok.

server {
    # ... je bestaande configuratie ...

    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; }
        # Gebruikt een externe plugin admin-ajax.php, sta dat dan toe in een aparte location
        location ~ \.php$ {
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
        }
    }
}

De combinatie van if en return is een vorm die Nginx veilig verwerkt. /wp-admin/admin-ajax.php wordt door functies van openbare pagina's (formulieren, oneindig scrollen en dergelijke) soms zonder inloggen aangeroepen. Beslis dus aan de hand van de functies van je site of je dat bestand van de beperking uitsluit.

Doorvoeren en controleren:

sudo nginx -t && sudo systemctl reload nginx

# Vanuit je eigen land: je krijgt 200 of 302 terug
curl -sI https://example.com/wp-login.php | head -1
# Controle van de beoordeling (voorbeeld: landcode in het log)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';

Om te zien hoe de site er vanuit het buitenland uitziet, open je wp-login.php via een VPN met een locatie in het buitenland of via een monitoringdienst buiten Japan, en controleer je of je een 403 krijgt.

Achter een CDN (zoals Cloudflare)

Via een CDN is $remote_addr het IP-adres van de CDN en wordt iedereen beoordeeld als bezoeker uit het land van de CDN. Herstel eerst het echte IP van de bezoeker met ngx_http_realip_module (realip-module).

# Voorbeeld voor Cloudflare. Ververs de IP-lijst regelmatig vanaf de officiële IP Ranges van Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... alle Cloudflare-reeksen opsommen ...
real_ip_header   CF-Connecting-IP;

geoip2 kijkt standaard naar $remote_addr, dus de beoordeling gebeurt op het echte IP nadat realip dat heeft vervangen. Ook Cloudflare zelf kan per land de toegang regelen (aangepaste WAF-regels). Gebruik je Cloudflare, dan is beperken aan de kant van Cloudflare eenvoudiger dan in Nginx. Zie ook Cloudflare instellen voor WordPress.

Grenzen van beperken per land

  • De beoordeling met GeoIP is een schatting op basis van de registratiegegevens van het IP-adres. Je omzeilt het met een VPN, een proxy of een tussenserver bij een buitenlandse cloud.
  • Bij mobiele netwerken en bedrijfsnetwerken kan een bezoeker worden beoordeeld als afkomstig uit een ander land dan waar hij zich bevindt. Ook kan een beheerder die in het buitenland op zakenreis is buitengesloten raken.
  • Gebruik beperken per land daarom als hulpmiddel om brute-force-pogingen op de login te verminderen, in combinatie met tweestapsverificatie, een limiet op inlogpogingen en wp-admin beveiligen met Basic-authenticatie.

Veelgestelde vragen

Wat is het verschil tussen de geoip-module en de geoip2-module van Nginx?

De oude geoip-module leest data in het formaat GeoIP Legacy (.dat), maar MaxMind verspreidt dat formaat niet meer. De geoip2-module (ngx_http_geoip2_module) leest het huidige formaat .mmdb en kan de gratis data van GeoLite2 gebruiken. Gebruik voor nieuwe configuraties geoip2.

Is GeoLite2 gratis? Moet ik me registreren?

Het is gratis, maar je hebt een MaxMind-account en een licentiesleutel nodig. Downloaden en periodiek bijwerken doe je met geoipupdate. De oude werkwijze waarbij je zonder sleutel rechtstreeks downloadt, werkt niet meer.

Voorkom ik ongeoorloofde WordPress-logins als ik per land beperk?

Het vermindert het aantal brute-force-pogingen, maar je kunt niet zeggen dat het ze voorkomt, omdat je het met een VPN of een tussenserver in het buitenland kunt omzeilen. Combineer het met een limiet op inlogpogingen, tweestapsverificatie, Basic-authenticatie en dergelijke.

Als ik Cloudflare gebruik, lijkt iedereen uit hetzelfde land te komen

Dat komt doordat de bron van de verbinding via een CDN het IP-adres van de CDN is. Herstel het echte IP met set_real_ip_from en real_ip_header CF-Connecting-IP voordat je beoordeelt. Je kunt ook per land beperken met de WAF van Cloudflare.

Kan ik met GeoLite2-City tot op stadsniveau beperken?

Ook codes van steden en regio's kun je in variabelen zetten, maar de nauwkeurigheid op stadsniveau is lager dan op landniveau, waardoor je gemakkelijk legitieme gebruikers buitensluit door een verkeerde beoordeling. Blijf voor toegangsbeheer bij het landniveau.

Samenvatting

  • Beperken per land in Nginx doe je tegenwoordig met GeoIP2 (ngx_http_geoip2_module + GeoLite2 .mmdb), met data die je bijwerkt via geoipupdate.
  • Zet de landcode met geoip2 in een variabele, bepaal met map of je toelaat of weigert, en geef return 403 in de location voor wp-login.php en /wp-admin/.
  • Herstel via een CDN eerst het echte IP en gebruik beperken per land als hulpmiddel naast tweestapsverificatie en dergelijke.

Gerelateerde artikelen

Bronnen: ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module

Wijzigingen: 2026-11-09 volledig herzien (de verouderde GeoLite-werkwijze waarvan de verspreiding is gestopt vervangen door de werkwijze met GeoIP2 en geoipupdate, een voorbeeld voor het beperken van het WordPress-beheer en een opmerking over CDN's toegevoegd). Dit artikel wordt uitgegeven door WordPress Hakase (Lightscend Co., Ltd.).

Vragen over WordPress? De uitgever van deze site zit in Japan en antwoordt in het Japans. Contact (Japans)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲