2026年11月12日
2026年11月12日
Ograniczanie dostępu według kraju w Nginx: GeoIP2 i GeoLite2
Ten artykuł jest zlokalizowaną wersją japońskiego oryginału. Przeczytaj japoński oryginał
Aby w Nginx ograniczyć dostęp według kraju, użyj modułu GeoIP2 (ngx_http_geoip2_module) i bazy GeoLite2 od MaxMind, zapisz kod kraju w zmiennej w bloku geoip2, a zezwolenie lub odmowę rozstrzygnij przez map — tak wygląda aktualna procedura (stan na listopad 2026). Stara metoda z wielu artykułów, czyli pobranie pliku .dat GeoLite przez wget, już nie działa, bo dystrybucja tych danych została zakończona.
Najpierw najważniejsze wnioski.
- Stary
ngx_http_geoip_module(GeoIP Legacy) nie nadaje się do nowych wdrożeń, ponieważ MaxMind zakończył dystrybucję danych w starym formacie. Przejdź na GeoIP2 (format.mmdb). - GeoLite2 jest darmowy, ale wymaga konta MaxMind i klucza licencyjnego; pobieranie i aktualizację wykonuje
geoipupdate. - Po stronie Nginx w bloku
geoip2tworzysz zmienną, np.$geoip2_country_code, wmapustalasz wartości 0 / 1 odpowiadająceallow/deny, a wlocationzwracaszreturn 403. - Jeśli witryna działa za CDN, np. Cloudflare, najpierw przywróć prawdziwy adres IP odwiedzającego przez
real_ip_header. W przeciwnym razie wszyscy zostaną rozpoznani jako kraj CDN. - Ograniczenie według kraju to tylko dodatkowa warstwa zmniejszająca liczbę ataków, którą da się obejść przez VPN lub pośrednika. Realistyczne jest stosowanie go do ekranu logowania i panelu administracyjnego, a nie do całej witryny.
Różnica między starym geoip a GeoIP2
| Pozycja | ngx_http_geoip_module (stary) | ngx_http_geoip2_module (GeoIP2) |
|---|---|---|
| Format danych | GeoIP Legacy (.dat) |
GeoIP2 (.mmdb) |
| Darmowe dane | Zakończone (dystrybucja skończyła się w 2019 r.) | GeoLite2 (wymaga konta i klucza licencyjnego) |
| Wymagana biblioteka | libGeoIP | libmaxminddb |
| Skąd wziąć moduł | Standard Nginx (--with-http_geoip_module) |
Moduł zewnętrzny leev/ngx_http_geoip2_module. Debian / Ubuntu mają gotowy pakiet |
| Zmienne | Stałe, np. $geoip_country_code |
Nazwy nadajesz sam w bloku geoip2 |
Jeśli w obecnej konfiguracji używasz geoip_country, baza danych przestała się aktualizować, więc wyniki są nieaktualne. Warto przy okazji przejść na GeoIP2.
Krok 1: zarejestruj się w MaxMind i utwórz klucz licencyjny
- Załóż bezpłatne konto na stronie GeoLite2 w MaxMind.
- Po zalogowaniu wygeneruj License Key w panelu konta (klucz jest wyświetlany tylko raz, więc go zapisz).
- Z baz danych potrzebujesz
GeoLite2-Country, jeśli wystarczy kraj, lubGeoLite2-City, jeśli potrzebne są miasta. Do ograniczenia według kraju wystarczy Country.
Warunki użytkowania (GeoLite2 End User License Agreement) zawierają zasady dotyczące redystrybucji i wyświetlania danych. Jeśli używasz ich tylko do rozpoznawania kraju na własnym serwerze, mieści się to zwykle w normie, ale warunki sprawdź przy rejestracji.
Krok 2: pobierz i aktualizuj bazę przez geoipupdate
GeoLite2 jest regularnie aktualizowany, więc zamiast pobierać go ręcznie, użyj geoipupdate (dokumentacja geoipupdate).
# Debian / Ubuntu
sudo apt install geoipupdate
# Rodzina RHEL (AlmaLinux / Rocky Linux) z EPEL
sudo dnf install geoipupdate
W pliku konfiguracyjnym /etc/GeoIP.conf wpisz identyfikator konta i klucz licencyjny.
AccountID 123456
LicenseKey tutaj wklej wygenerowany klucz
EditionIDs GeoLite2-Country
# Katalog docelowy to domyślny katalog pakietu (Debian / Ubuntu: /var/lib/GeoIP, w innych zwykle /usr/share/GeoIP).
# Aby go zmienić: DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/ # jeśli jest GeoLite2-Country.mmdb, wszystko się udało
Pakietowa wersja geoipupdate ma skonfigurowane cykliczne uruchamianie przez timer systemd lub cron (sprawdzisz to poleceniem systemctl list-timers | grep geoip). Jeśli go nie ma, dodaj wpis cron uruchamiany mniej więcej raz w tygodniu.
Krok 3: zainstaluj w Nginx moduł GeoIP2
Debian / Ubuntu (Nginx z apt)
sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/ # pojawi się 50-mod-http-geoip2.conf
nginx -t
Nginx z pakietów nginx.org lub zbudowany ze źródeł
Zainstaluj libmaxminddb, a następnie zbuduj moduł dynamiczny ze źródeł w tej samej wersji, co działający Nginx.
sudo apt install libmaxminddb-dev # w rodzinie 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 # wersję dopasuj do 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/
Załaduj moduł na początku nginx.conf (w wersji pakietowej jest to robione automatycznie).
load_module modules/ngx_http_geoip2_module.so;
Krok 4: zapisz kod kraju w zmiennej i rozstrzygnij zezwolenie lub odmowę
Umieść to w bloku http. W bloku geoip2 zapisujesz kod kraju w zmiennej, a w map nadajesz 1 dozwolonym krajom i 0 pozostałym.
http {
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_country_code country iso_code;
}
# Kraje, którym wolno wejść do panelu (dwuliterowe kody ISO 3166-1)
map $geoip2_country_code $admin_allowed {
default 0;
JP 1;
"" 1; # Adresów, których nie da się rozpoznać (np. prywatnych IP), nie blokujemy. Jeśli chcesz je odrzucać, wpisz 0
}
}
auto_reload to odstęp, co jaki Nginx ponownie wczytuje bazę podmienioną przez geoipupdate, bez restartu.
Krok 5: ogranicz tylko logowanie i panel administracyjny WordPress
Poniższy przykład nie ogranicza stron publicznych, a kraj sprawdza tylko dla wp-login.php i /wp-admin/. Umieść go w bloku server.
server {
# ... dotychczasowa konfiguracja ...
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; }
# Jeśli admin-ajax.php wywołuje zewnętrzna wtyczka, zezwól na niego w osobnym location
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
}
Połączenie if z return to postać, którą Nginx obsługuje bezpiecznie. Plik /wp-admin/admin-ajax.php bywa wywoływany bez logowania przez funkcje stron publicznych (formularze, nieskończone przewijanie itp.), więc to, czy wyłączyć go spod ograniczenia, zależy od funkcji witryny.
Zastosowanie i sprawdzenie:
sudo nginx -t && sudo systemctl reload nginx
# Z własnego kraju: powinien wrócić kod 200 lub 302
curl -sI https://example.com/wp-login.php | head -1
# Sprawdzenie rozpoznania (przykład z kodem kraju w logu)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';
Aby zobaczyć, jak witryna wygląda z zagranicy, wejdź na wp-login.php przez VPN z zagranicznym serwerem lub z zagranicznej usługi monitorującej i sprawdź, czy dostajesz 403.
Gdy witryna działa za CDN (np. Cloudflare)
Przez CDN $remote_addr to adres IP CDN, więc wszyscy są rozpoznawani jako kraj CDN. Najpierw przywróć prawdziwy adres IP odwiedzającego za pomocą ngx_http_realip_module (moduł realip).
# Przykład dla Cloudflare. Listę adresów IP regularnie aktualizuj według oficjalnych IP Ranges Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... wypisz wszystkie zakresy Cloudflare ...
real_ip_header CF-Connecting-IP;
geoip2 domyślnie patrzy na $remote_addr, więc kraj jest ustalany na podstawie prawdziwego adresu IP po podmianie przez realip. Sam Cloudflare ma też kontrolę dostępu według kraju (własne reguły WAF), więc jeśli z niego korzystasz, prościej ustawić ograniczenie po stronie Cloudflare niż w Nginx. Zobacz też Konfiguracja Cloudflare dla WordPress.
Ograniczenia blokowania według kraju
- Rozpoznanie GeoIP to oszacowanie na podstawie danych rejestracyjnych adresu IP i można je obejść przez VPN, serwery proxy lub pośredników w zagranicznej chmurze.
- W sieciach komórkowych i firmowych adres bywa przypisany do innego kraju niż rzeczywista lokalizacja. W praktyce może to też zablokować administratora, który wyjechał za granicę.
- Dlatego blokadę według kraju stosuj jako dodatkowe zabezpieczenie zmniejszające liczbę ataków brute force na logowanie, razem z uwierzytelnianiem dwuskładnikowym, limitem prób logowania i ochroną wp-admin przez uwierzytelnianie Basic.
Najczęstsze pytania
Czym różni się moduł geoip od modułu geoip2 w Nginx
Stary moduł geoip czyta dane w formacie GeoIP Legacy (.dat), ale MaxMind zakończył dystrybucję tego formatu. Moduł geoip2 (ngx_http_geoip2_module) czyta obecny format .mmdb i pozwala używać darmowych danych GeoLite2. Nowe konfiguracje twórz z geoip2.
Czy GeoLite2 jest darmowy i czy trzeba się rejestrować
Jest darmowy, ale wymaga konta MaxMind i wygenerowania klucza licencyjnego. Pobieranie i regularną aktualizację wykonuje geoipupdate. Stara metoda bezpośredniego pobierania bez klucza nie działa.
Czy ograniczenie według kraju zapobiegnie nieautoryzowanym logowaniom do WordPress
Zmniejsza liczbę prób brute force, ale ponieważ da się je obejść przez VPN lub pośredników na zagranicznych serwerach, nie można powiedzieć, że im zapobiega. Połącz je z limitem prób logowania, uwierzytelnianiem dwuskładnikowym, uwierzytelnianiem Basic itp.
Przy Cloudflare wszyscy mają ten sam kraj
Dzieje się tak, ponieważ przez CDN źródłem połączenia jest adres IP CDN. Zanim rozpoznasz kraj, przywróć prawdziwy adres IP przez set_real_ip_from i real_ip_header CF-Connecting-IP. Możesz też ograniczać według kraju w WAF Cloudflare.
Czy z GeoLite2-City można ograniczać aż do miasta
Kody miast i regionów też można zapisać w zmiennych, ale dokładność na poziomie miasta jest niższa niż na poziomie kraju i łatwo przez pomyłkę zablokować uprawnionych użytkowników. Do kontroli dostępu najlepiej poprzestać na poziomie kraju.
Podsumowanie
- Obecne ograniczenie według kraju w Nginx realizujesz przez GeoIP2 (ngx_http_geoip2_module + GeoLite2
.mmdb), a dane aktualizujesz przezgeoipupdate. - Kod kraju zapisujesz w zmiennej przez
geoip2, zezwolenie lub odmowę ustalasz wmap, a wlocationdlawp-login.phpi/wp-admin/zwracaszreturn 403. - Za CDN najpierw przywróć prawdziwy adres IP, a blokadę według kraju traktuj jako dodatek do uwierzytelniania dwuskładnikowego i podobnych zabezpieczeń.
Powiązane artykuły
- Jak ograniczyć dostęp do REST API w WordPress
- Jak utworzyć hasło uwierzytelniania Basic w Apache za pomocą htpasswd | ochrona wp-admin
- Kompletny przewodnik po konfiguracji Cloudflare dla WordPress
Źródła: ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module
Historia zmian: 2026-11-09 pełna rewizja (nieaktualną procedurę ze starym GeoLite, którego dystrybucję zakończono, zastąpiono procedurą z GeoIP2 i geoipupdate, dodano przykład ograniczenia panelu WordPress i uwagi o CDN). Ten artykuł jest prowadzony przez WordPress Hakase (Lightscend Co., Ltd.).
Pytania o WordPress? Wydawca tej witryny ma siedzibę w Japonii i odpowiada po japońsku. Kontakt (po japońsku)