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 в Nginx: регистрация в MaxMind, получение базы через geoipupdate, подключение модуля, проверка через geoip2 и map, ограничение в location

Чем 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 и создайте лицензионный ключ

  1. Создайте бесплатную учётную запись на странице MaxMind GeoLite2.
  2. После входа выпустите License Key в панели управления учётной записью (ключ показывается только в момент создания, поэтому сохраните его).
  3. Из баз нужна 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; ограничение по странам применяйте как вспомогательную меру вместе с двухфакторной аутентификацией и подобными средствами.

Похожие статьи

Источники: 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? Издатель сайта находится в Японии и отвечает по-японски. Связаться (по-японски)

お気軽にご相談ください

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