2026年11月12日
2026年11月12日
Nginx GeoIP2: обмеження доступу за країнами для WordPress
Ця стаття — локалізована версія японського оригіналу. Читати японський оригінал
Щоб в Nginx обмежити доступ за країнами, скористайтеся модулем GeoIP2 (ngx_http_geoip2_module) і базою MaxMind GeoLite2: блок geoip2 записує код країни у змінну, а map вирішує, дозволити чи заборонити доступ. Так це робиться станом на листопад 2026 року. Старий спосіб із давніх статей — завантажити .dat-файл GeoLite через wget — більше не працює, бо роздачу цих даних припинено.
Коротко про головне.
- Старий
ngx_http_geoip_module(GeoIP Legacy) для нових налаштувань непридатний, бо MaxMind припинила роздачу даних у старому форматі. Переходьте на GeoIP2 (формат.mmdb). - GeoLite2 безкоштовна, але потрібні обліковий запис MaxMind і ліцензійний ключ; завантажувати й оновлювати базу слід через
geoipupdate. - У Nginx блок
geoip2створює змінну на кшталт$geoip2_country_code,mapвизначає 0 / 1 (аналогallow/deny), аlocationповертаєreturn 403. - Якщо сайт працює через CDN на кшталт Cloudflare, спершу відновіть справжню IP-адресу відвідувача через
real_ip_header, інакше всі запити визначатимуться як такі, що надійшли з країни CDN. - Обмеження за країнами лише допомагає зменшити кількість атак: його можна обійти через VPN або проксі. Реалістичніше застосовувати його не до всього сайту, а до сторінки входу та адмінки.
Чим старий geoip відрізняється від GeoIP2
| Параметр | ngx_http_geoip_module (старий) | ngx_http_geoip2_module (GeoIP2) |
|---|---|---|
| Формат даних | GeoIP Legacy (.dat) |
GeoIP2 (.mmdb) |
| Безкоштовні дані | Припинено (роздачу завершили у 2019 році) | GeoLite2 (потрібні обліковий запис і ліцензійний ключ) |
| Потрібна бібліотека | libGeoIP | libmaxminddb |
| Де взяти модуль | Входить до стандартного Nginx (--with-http_geoip_module) |
Сторонній модуль leev/ngx_http_geoip2_module. Для Debian / Ubuntu є пакет |
| Змінні | Фіксовані, як-от $geoip_country_code |
Імена задаєте самі в блоці geoip2 |
Якщо у ваших налаштуваннях досі стоїть geoip_country, оновлення бази зупинилися, і визначення країни застаріло. Скористайтеся нагодою й перейдіть на GeoIP2.
Крок 1. Зареєструйтеся в MaxMind і створіть ліцензійний ключ
- Створіть безкоштовний обліковий запис на сторінці MaxMind GeoLite2.
- Після входу в панелі керування акаунтом згенеруйте License Key (ключ показується лише під час створення, тож збережіть його).
- Із баз даних вам потрібна
GeoLite2-Country, якщо йдеться лише про країни, абоGeoLite2-City, якщо потрібні й міста. Для обмеження за країнами достатньо Country.
Умови використання (GeoLite2 End User License Agreement) містять правила щодо повторного поширення й показу даних. Якщо ви використовуєте базу лише для визначення країни на власному сервері, це зазвичай у межах дозволеного, але перевірте умови під час реєстрації.
Крок 2. Отримайте й оновлюйте базу через geoipupdate
GeoLite2 оновлюється регулярно, тому не завантажуйте її вручну, а користуйтеся geoipupdate (документація geoipupdate).
# Debian / Ubuntu
sudo apt install geoipupdate
# Сімейство RHEL (AlmaLinux / Rocky Linux) — з EPEL
sudo dnf install geoipupdate
У файлі налаштувань /etc/GeoIP.conf вкажіть ID облікового запису та ліцензійний ключ.
AccountID 123456
LicenseKey виданий вами ключ
EditionIDs GeoLite2-Country
# Каталог збереження — типовий для дистрибутива (у Debian / Ubuntu це /var/lib/GeoIP, в інших найчастіше /usr/share/GeoIP).
# Щоб змінити його, додайте DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/ # Якщо є GeoLite2-Country.mmdb — усе вдалося
Пакетна версія geoipupdate налаштована на періодичний запуск через таймер systemd або cron (перевірте командою systemctl list-timers | grep geoip). Якщо цього немає, додайте завдання cron приблизно раз на тиждень.
Крок 3. Підключіть модуль GeoIP2 до Nginx
Debian / Ubuntu (Nginx з apt)
sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/ # Тут з’явиться 50-mod-http-geoip2.conf
nginx -t
Nginx із пакета nginx.org або зібраний із вихідного коду
Установіть libmaxminddb, а потім зберіть динамічний модуль із вихідного коду тієї самої версії, що й працюючий Nginx.
sudo apt install libmaxminddb-dev # У сімействі 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 # Версію підберіть за виводом 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/
Підключіть модуль на початку nginx.conf (у пакетній версії це робиться автоматично).
load_module modules/ngx_http_geoip2_module.so;
Крок 4. Запишіть код країни у змінну й вирішіть, дозволити чи заборонити доступ
Додайте це в блок http. Блок geoip2 записує код країни у змінну, а map ставить 1 для дозволених країн і 0 для решти.
http {
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_country_code country iso_code;
}
# Країни, яким дозволено адмінку (двобуквені коди ISO 3166-1)
map $geoip2_country_code $admin_allowed {
default 0;
JP 1;
"" 1; # Якщо країну визначити неможливо (приватні IP тощо) — дозволяємо. Щоб забороняти, поставте 0
}
}
auto_reload — це інтервал, з яким Nginx перечитує базу, замінену geoipupdate, без перезапуску.
Крок 5. Обмежте лише сторінку входу й адмінку WordPress
Це приклад, у якому публічні сторінки не обмежуються, а за країнами фільтруються тільки wp-login.php і /wp-admin/. Додайте його в блок server.
server {
# ... наявні налаштування ...
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; }
# Якщо admin-ajax.php використовують зовнішні плагіни, дозвольте його в окремому location
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
}
Поєднання if і return Nginx обробляє безпечно. /wp-admin/admin-ajax.php іноді викликають без входу в обліковий запис функції публічних сторінок (форми, нескінченне прокручування тощо), тож вирішіть, чи виключати його з обмеження, залежно від функцій вашого сайту.
Застосування й перевірка:
sudo nginx -t && sudo systemctl reload nginx
# З вашої країни: повертається 200 або 302
curl -sI https://example.com/wp-login.php | head -1
# Перевірка визначення (приклад виведення коду країни в лог)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';
Щоб побачити, як сайт виглядає із-за кордону, відкрийте wp-login.php через VPN із зарубіжним вузлом або із закордонного сервісу моніторингу й переконайтеся, що отримуєте 403.
Якщо сайт працює через CDN (наприклад, Cloudflare)
Через CDN $remote_addr стає IP-адресою CDN, і всі відвідувачі визначаються як такі, що надійшли з країни CDN. Спершу відновіть справжню IP-адресу відвідувача за допомогою ngx_http_realip_module (модуль realip).
# Приклад для Cloudflare. Список IP регулярно оновлюйте за офіційною сторінкою IP Ranges Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... перелічіть усі діапазони Cloudflare ...
real_ip_header CF-Connecting-IP;
За замовчуванням geoip2 дивиться на $remote_addr, тому країна визначається за справжньою IP-адресою, підміненою realip. У самого Cloudflare також є обмеження доступу за країнами (спеціальні правила WAF), тож якщо ви користуєтеся Cloudflare, простіше обмежити доступ на його боці, а не в Nginx. Див. також Налаштування Cloudflare для WordPress.
Обмеження блокування за країнами
- Визначення GeoIP — це оцінка за реєстраційними даними IP-адреси, тож його можна обійти через VPN, проксі або ретрансляцію із закордонної хмари.
- У мобільних мережах і корпоративних мережах країна може визначитися не там, де користувач насправді перебуває. Також виникає практична проблема: адміністратор у відрядженні за кордоном опиняється за дверима.
- Тому блокування за країнами застосовуйте як допоміжний засіб проти підбору паролів у поєднанні з двофакторною автентифікацією, обмеженням кількості спроб входу та захистом wp-admin через Basic-автентифікацію.
Поширені запитання
Чим модуль geoip в Nginx відрізняється від geoip2
Старий модуль geoip читає дані у форматі GeoIP Legacy (.dat), але MaxMind припинила роздачу цього формату. Модуль geoip2 (ngx_http_geoip2_module) читає поточний формат .mmdb і дає змогу користуватися безкоштовними даними GeoLite2. Нові налаштування робіть на geoip2.
Чи безкоштовна GeoLite2 і чи потрібна реєстрація
Вона безкоштовна, але потрібні обліковий запис MaxMind і ліцензійний ключ. Завантажуйте й регулярно оновлюйте базу через geoipupdate. Старий спосіб прямого завантаження без ключа не працює.
Чи захистить обмеження за країнами WordPress від несанкціонованого входу
Воно зменшує кількість спроб підбору, але захистом його назвати не можна: його обходять через VPN або ретрансляцію із закордонних серверів. Поєднуйте його з обмеженням кількості спроб входу, двофакторною автентифікацією, Basic-автентифікацією тощо.
Через Cloudflare всі відвідувачі виглядають як з однієї країни
Це відбувається тому, що через CDN джерелом з’єднання стає IP-адреса CDN. Відновіть справжню IP-адресу за допомогою set_real_ip_from і real_ip_header CF-Connecting-IP, а вже потім визначайте країну. Також можна обмежити доступ за країнами через WAF Cloudflare.
Чи можна з GeoLite2-City обмежувати доступ до рівня міст
У змінні можна записувати й коди міст та регіонів, але точність на рівні міста нижча, ніж на рівні країни, і легітимних користувачів у разі помилок блокуватимуть частіше. Для контролю доступу безпечніше обмежитися рівнем країни.
Підсумок
- Обмеження за країнами в сучасному Nginx виконується через GeoIP2 (ngx_http_geoip2_module + GeoLite2
.mmdb), а дані оновлюються черезgeoipupdate. - Блок
geoip2записує код країни у змінну,mapвирішує, дозволити чи заборонити доступ, аlocationдляwp-login.phpі/wp-admin/повертаєreturn 403. - Якщо сайт працює через CDN, спершу відновіть справжню IP-адресу, а обмеження за країнами використовуйте як допоміжний захід разом із двофакторною автентифікацією тощо.
Пов’язані статті
- Як обмежити доступ до REST API WordPress
- Як створити пароль Basic-автентифікації Apache за допомогою htpasswd: захист wp-admin
- Повний посібник із налаштування Cloudflare для WordPress
Джерела: ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module
Історія оновлень: 2026-11-09 — повне переписування (застарілу процедуру з GeoLite, роздачу якої припинено, замінено процедурою з GeoIP2 та geoipupdate, додано приклад обмеження адмінки WordPress і примітку про CDN). Цю статтю підтримує WordPress Hakase (Lightscend Co., Ltd.).
Маєте запитання щодо WordPress? Видавець сайту перебуває в Японії й відповідає японською. Написати нам (японською)