До основного вмісту

GeoIP у Nginx: доступ і блокування запитів за країнами

Nginx · 18.10.2026 · 4 хв читання
Ілюстрація до статті «GeoIP у Nginx: доступ і блокування запитів за країнами»

GeoIP дозволяє nginx приймати рішення за країною відвідувача — показати локалізовану версію сайту, закрити доступ для регіонів, де легітимних клієнтів немає, або просто зібрати статистику за географією трафіку. Модуль не замінює файрвол і не захищає від розподіленої атаки: він працює на рівні HTTP уже після того, як з'єднання дійшло до nginx, і підходить для точкових правил, а не для захисту від напливу запитів.

Два модулі GeoIP і чому geoip2 кращий

У nginx є два модулі для визначення країни за IP: застарілий ngx_http_geoip_module, що працює з бінарними базами легасі-формату GeoIP, і ngx_http_geoip2_module, який читає сучасні бази формату .mmdb — GeoLite2 або платний GeoIP2 від MaxMind. Легасі-бази GeoIP компанія MaxMind давно не оновлює, тому для нових серверів сенсу у старому модулі немає.

Модуль geoip2 не входить до базової збірки nginx — це динамічний модуль, який встановлюється окремим пакетом з офіційного репозиторію nginx або збирається з вихідного коду з опцією --add-dynamic-module. Базове налаштування самого nginx, до якого додається цей модуль, описане у статті про налаштування Nginx для сайту на VDS.

Встановлення модуля і бази GeoLite2

Після встановлення пакета модуль підключається директивою load_module на початку основного файлу конфігурації, до блоку events. База GeoLite2-Country або GeoLite2-City завантажується з сайту MaxMind — для безкоштовних баз потрібна реєстрація і ключ ліцензії, а їх оновлення зазвичай автоматизують окремим завданням cron з утилітою geoipupdate.

Директива geoip2 оголошується у блоці http один раз і пов'язує шлях до файлу бази зі змінними, які можна використовувати далі у конфігурації, — кодом країни, континентом або назвою міста, якщо використовується база City.

load_module modules/ngx_http_geoip2_module.so;

http {
    geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
        auto_reload 60m;
        $geoip2_data_country_code country iso_code;
    }

    map $geoip2_data_country_code $country_blocked {
        default 0;
        RU 1;
        BY 1;
    }
}

Блокування країн через map і return 403

Змінна $geoip2_data_country_code підставляється у map, який перетворює код країни на простий прапорець 0 або 1. Всередині server або location лишається перевірити цей прапорець директивою if і повернути 403 без звернення до бекенду — запит із заблокованої країни навіть не доходить до PHP-FPM чи проксі-застосунку.

СпосібРівеньКоли підходить
geoip2 у nginxHTTP, на самому серверіточкові правила для окремих location чи доменів
Firewall-правила Cloudflareперед сервером, на CDNмасове блокування країн ще до того, як запит дійшов до VDS
limit_req / limit_connHTTP, на самому серверізахист від напливу запитів незалежно від географії

Ці три способи не виключають один одного: geoip2 вирішує, звідки запит, Cloudflare фільтрує трафік ще на межі мережі, а limit_req і limit_conn обмежують швидкість запитів незалежно від країни.

Де це доречно, а де краще блокувати на Cloudflare

Правило на рівні nginx все одно приймає TCP-з'єднання і витрачає ресурси процесу на обробку заголовків запиту, перш ніж повернути 403. Для одиночної VDS без CDN це не критично, але за серйозного обсягу трафіку із заблокованих країн розумніше не пускати його на сервер взагалі.

Якщо перед сайтом уже стоїть Cloudflare, блокування за країною логічніше налаштувати там — воно описане у статті про Firewall-правила Cloudflare. Для сайтів без CDN geoip2 у nginx лишається робочим варіантом без додаткових сервісів.

Чек-лист перед включенням

Перш ніж включати блокування за країнами у продакшені, варто пройти наступні пункти — помилка у правилі відрізає не абʼюз, а частину реальних відвідувачів.

  • Перевірено, що IP реальних користувачів сайту, включно з клієнтами у відрядженнях і на VPN, не потрапляють у список заблокованих країн помилково.
  • База GeoLite2 оновлюється регулярно — застаріла база неправильно визначає країну для нових підмереж.
  • Правило протестоване через curl із заголовком, що імітує IP із потрібної країни, перед включенням на реальному трафіку.
  • Для API і вебхуків платіжних систем зроблено виняток, якщо їхні сервери фізично розташовані у заблокованому регіоні.
  • Логи nginx фіксують код країни в окремій змінній, щоб потім перевірити, скільки запитів правило реально відрізало.

Часті питання

Чи можна заблокувати не всю країну, а окремий регіон або місто?

Так, якщо використовується база GeoLite2-City замість GeoLite2-Country — вона дає змінні з назвою міста і регіону, але точність визначення міста помітно нижча за точність визначення країни, особливо для мобільних і корпоративних підмереж.

Що робити, якщо легітимний клієнт пише про блокування 403?

Перевірити його реальний IP і код країни за базою GeoLite2 вручну — іноді провайдер маршрутизує трафік через вузол в іншій країні, і блокування спрацьовує помилково. У такій ситуації простіше додати його IP до окремого allowlist, ніж знімати правило цілком.

Чи потрібно перезапускати nginx після оновлення бази GeoLite2?

Ні, якщо у блоці geoip2 вказано auto_reload з інтервалом — nginx сам підхоплює новий файл бази за розкладом. Без цієї директиви зміни застосовуються лише після reload конфігурації.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці