Как включить GeoIP в Nginx: переменные для логов и заголовков
Пошагово включаем GeoIP в Nginx на BitrixVM (VPS, CentOS 9): установка модуля и баз, переменные в лог и заголовки, проверка и типичные ошибки.
Требования
- BitrixVM 9+ на CentOS Stream 9+
- Nginx из официального репозитория nginx.org
- Понимание структуры конфигов Nginx в BitrixVM (nginx + httpd)
Как включить GeoIP в Nginx: переменные для логов и заголовков
Запрос «как включить GeoIP в Nginx и получить переменные для логов и заголовков» чаще всего всплывает у тех, кто ведёт аудит трафика на VPS: нужно видеть страну/город в access.log или прокинуть страну в приложение (например, Bitrix за Apache). В конце будет рабочая конфигурация для BitrixVM (nginx+httpd), проверка, и список типичных проблем.
В чём проблема
Симптом обычно один из этих:
- В конфиг добавили
geoip_country/geoip_city, а Nginx на перезагрузке падает:
nginx: [emerg] unknown directive "geoip_country" in /etc/nginx/nginx.conf:XX
- Или модуль подключили, но переменные пустые — в логах вместо страны
-:
1.2.3.4 - - [16/Feb/2026:12:10:11 +0000] "GET / HTTP/2.0" 200 123 "-" "-" country=- city=-
Причины ровно две:
- Модуль не загружен (динамические модули подключаются через
load_module, иначе директивы неизвестны). Официальный модуль называетсяngx_http_geoip_moduleи создаёт переменные на основе баз MaxMind. (nginx.org) - Нет базы или она не в том формате. Важно: legacy GeoLite (.dat) давно сняты с раздачи, MaxMind официально прекратил GeoLite Legacy. Поэтому старые команды с
GeoIP.dat.gzпо прямым ссылкам сегодня чаще мёртвые, чем живые. (MaxMind)
Ещё по современности (2025–2026): если вам нужна актуальная бесплатная геобаза, это GeoLite2 (MMDB) и по сути это уже модуль GeoIP2 (в NGINX Plus он официальный). (docs.nginx.com)
Но в BitrixVM обычно стоит open source Nginx — там штатный модуль ngx_http_geoip_module работает с legacy-форматом. Поэтому ниже — два практичных пути: (A) включить legacy GeoIP модуль с .dat, если база у вас есть (коммерческая/внутренняя), (B) если у вас NGINX Plus — включить GeoIP2 как правильный вариант на будущее.
Рабочее решение
Ниже шаги ориентированы на BitrixVM 9+ (CentOS Stream 9+, nginx + httpd). Все команды выполняются из-под root, sudo не используем.
1) Убедиться, что Nginx установлен из официального репозитория
Официальные пакеты Nginx ставятся из репозитория nginx.org. Инструкция по подключению репозитория — на сайте NGINX. (nginx.org)
Проверка:
nginx -v
rpm -qa | grep -E '^nginx'
Если Nginx не из nginx.org — дальше тоже можно жить, но пакеты модулей и путь к .so могут отличаться.
2) Установить динамический модуль GeoIP (legacy)
Пакет модуля на RHEL/CentOS-семействе обычно называется nginx-module-geoip (динамический модуль). Сам принцип — модуль ставится отдельно, затем подключается через load_module. (nginx.org)
Команды:
dnf makecache
dnf install -y nginx-module-geoip
Проверим, что файл модуля появился:
ls -la /usr/lib64/nginx/modules | grep geoip || true
Ожидаемо увидеть что-то вроде:
ngx_http_geoip_module.so
3) Подготовить каталог под базы GeoIP
Создадим каталог, куда будем класть базы (как минимум country, опционально city):
mkdir -p /etc/nginx/geoip
chmod 0755 /etc/nginx/geoip
Важное примечание про базы (без розовых очков)
- Официальный модуль
ngx_http_geoip_moduleожидает предкомпилированные базы MaxMind legacy формата. (nginx.org) - Бесплатные GeoLite Legacy базы официально прекращены (их больше не обновляют и не раздают). (MaxMind)
Что делать на практике:
- Если у вас уже есть
GeoIP.dat/GeoLiteCity.dat(из старых проектов, из внутреннего артефакт-хранилища, из коммерческой подписки) — кладём их в/etc/nginx/geoip/. - Если нет — не тратьте время на “магические” левые ссылки: проще и правильнее перейти на GeoIP2 (см. путь B ниже) или использовать GeoIP только для грубой аналитики через внешний сервис.
Для варианта A предполагаем, что файлы у вас есть:
# пример: вы загрузили базы сами и положили в каталог
ls -la /etc/nginx/geoip
Ожидаемые имена (можно свои, главное путь правильно указать в конфиге):
/etc/nginx/geoip/GeoIP.dat/etc/nginx/geoip/GeoLiteCity.dat
4) Подключить модуль и базы в конфиге Nginx (BitrixVM)
Где править в BitrixVM
В BitrixVM конфигурация обычно разнесена, но базовый путь стандартный:
- главный файл:
/etc/nginx/nginx.conf - дополнительные:
/etc/nginx/conf.d/*.conf(и/или bitrix-специфичные include)
Нам важно соблюсти правило Nginx: load_module допускается только в основном контексте (верх файла, до events {} / http {}). (nginx.org)
Сделаем аккуратно: создадим отдельный файл и подключим его в nginx.conf, если у вас уже есть include для модулей. Если include нет — вставьте строку load_module прямо в начало nginx.conf.
Вариант 1 (предпочтительно): отдельный файл
Создаём /etc/nginx/conf.d/00-geoip-load.conf (если у вас conf.d инклюдится в main-контексте — это редкость). В большинстве схем conf.d подключается внутри http {}, поэтому этот вариант может не сработать.
Вариант 2 (надёжно): правим /etc/nginx/nginx.conf
Открываем /etc/nginx/nginx.conf и добавляем в самое начало:
load_module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so";
Дальше — внутри http {} добавляем пути к базам:
http {
geoip_country /etc/nginx/geoip/GeoIP.dat;
geoip_city /etc/nginx/geoip/GeoLiteCity.dat;
# ...
}
Это включает переменные $geoip_country_code, $geoip_country_name и пачку city-переменных. Список переменных и назначение описаны в документации модуля. (nginx.org)
5) Добавить GeoIP в access.log и прокинуть заголовки к Apache/приложению
5.1. Логирование (быстро увидеть пользу)
В http {} определим формат лога, где будут страна/город:
log_format main_geoip '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'country=$geoip_country_code country_name="$geoip_country_name" '
'city="$geoip_city" lat=$geoip_latitude lon=$geoip_longitude';
И используем его для access.log:
access_log /var/log/nginx/access.log main_geoip;
Если у вас уже задан свой
log_formatв BitrixVM — не ломайте чужое. Добавьте новыйmain_geoipи подключите его точечно на нужномserver {}черезaccess_log ... main_geoip;.
5.2. Заголовки в апстрим (nginx -> httpd -> Bitrix)
Если Nginx проксирует в Apache (типично для BitrixVM), вы можете прокинуть страну/город в бекенд заголовками. В вашем server {} или location ~ \.php$ (где стоит proxy_pass или upstream на httpd) добавьте:
proxy_set_header X-GeoIP-Country $geoip_country_code;
proxy_set_header X-GeoIP-Country-Name $geoip_country_name;
proxy_set_header X-GeoIP-City $geoip_city;
Так приложение сможет читать это из $_SERVER['HTTP_X_GEOIP_COUNTRY'] и т.д.
6) Если перед Nginx есть прокси/балансировщик: geoip_proxy
Если Nginx стоит не “на краю”, а за прокси (Cloudflare, ELB, внешний балансировщик), GeoIP будет смотреть на IP прокси, а не клиента. Для этого модуль поддерживает geoip_proxy и geoip_proxy_recursive и учитывает X-Forwarded-For. (nginx.org)
Пример в http {}:
geoip_proxy 10.0.16.0/26;
geoip_proxy_recursive on;
Диапазон подставьте свой (подсеть балансировщика/прокси).
Проверка результата
- Проверяем синтаксис конфига:
nginx -t
Ожидаемо:
syntax is ok
test is successful
- Перезагружаем:
systemctl reload nginx
- Дёргаем сайт и смотрим лог:
curl -I https://your-domain.tld/ | head
tail -n 5 /var/log/nginx/access.log
В конце строки лога должны появиться country=XX и другие поля. Если видите country=- — значит модуль жив, но база не отрабатывает (см. типичные ошибки ниже).
Типичные ошибки
❌ 1) unknown directive "geoip_country"
Причина: модуль не загружен через load_module или установлен не тот пакет.
Как исправить:
- убедитесь, что модуль установлен:
dnf install -y nginx-module-geoip - проверьте наличие файла:
ls /usr/lib64/nginx/modules/ngx_http_geoip_module.so - проверьте, что
load_moduleстоит в самом верху/etc/nginx/nginx.conf(доhttp {}), иначе Nginx его просто не увидит. (nginx.org)
❌ 2) Nginx стартует, но GeoIP-переменные пустые
Причина: база отсутствует/не читается/не legacy формата. Legacy GeoLite официально прекращены — это частая ловушка у инструкций “из 2016”. (MaxMind)
Как исправить:
- проверьте файлы:
ls -la /etc/nginx/geoip - проверьте права (Nginx должен читать):
chmod 0644 /etc/nginx/geoip/*.dat - если базы нет — планируйте переход на GeoLite2 + GeoIP2 модуль (см. ниже, путь B). (docs.nginx.com)
❌ 3) Хотите “закрыть страны” и тянет написать if
Причина: в Nginx if — не как в языках программирования. Есть известная рекомендация избегать сложных if-конструкций, и использовать map. При этом даже NGINX-экосистема признаёт, что безопасные случаи есть (обычно return/rewrite). (nginx.org)
Как исправить (без фанатизма):
- для маршрутизации/флагов используйте
map(переменная вычисляется один раз и дальше используется в логике) - если всё-таки нужен
if, ограничьте его до “проверка → return”, безset, без вложенных rewrite-цепочек (иначе потом сложно отлаживать). (nginx.org)
Где применять
- Prod на VPS (BitrixVM 9+, CentOS 9+): добавить страну/город в логи, передавать в приложение, включать доп. метрики в мониторинг.
- Docker: удобно, если Nginx на периметре контейнеров и вам нужно логировать географию запросов (но с базами там отдельная история).
- CI/CD: можно проверять
nginx -tи деплоить конфиги автоматически, чтобы GeoIP не ронял nginx на бою. - Связка nginx + httpd: прокидывайте
X-GeoIP-*заголовки в Apache и дальше в Bitrix, чтобы не городить логику в PHP.
Сниппеты по статье: Nginx GeoIP: load_module и базы .dat · log_format и заголовки X-GeoIP · geoip_proxy за прокси/балансировщиком · Проверка модуля и баз (bash)
Внутренние ссылки по теме (чтобы собрать цепочку на сайте):
Путь B (коротко, но честно): GeoIP2 вместо legacy в 2025–2026
Если ваша цель — актуальная бесплатная геобаза, то правильная база — GeoLite2 (MMDB), а правильный модуль — GeoIP2. В документации NGINX Plus GeoIP2 модуль описан как официальный динамический модуль. (docs.nginx.com)
Legacy GeoIP/GeoLite в виде .dat в 2025–2026 — это в основном “наследие”, которое живёт только если у вас уже есть источник баз.



Комментарии