2026年11月12日
2026年11月12日
Nginx GeoIP2: ограничение доступа по странам для WordPress
Эта статья — локализованная версия японского оригинала. Читать японский оригинал
Чтобы ограничить доступ к Nginx по странам, на ноябрь 2026 года нужно подключить модуль GeoIP2 (ngx_http_geoip2_module) и базу MaxMind GeoLite2, записать код страны в переменную блоком geoip2 и решить, пускать или нет, через map. Старые инструкции, где нужно скачать .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 и промежуточные серверы. Практичнее применять его не ко всему сайту, а к странице входа и админ-панели.
Чем GeoIP2 отличается от старого geoip
| Параметр | 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, аreturn 403задаётся вlocationдляwp-login.phpи/wp-admin/. - Если сайт за 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? Издатель сайта находится в Японии и отвечает по-японски. Связаться (по-японски)