← Назад в блог

Как включить GeoIP в Nginx: переменные для логов и заголовков

Пошагово включаем GeoIP в Nginx на BitrixVM (VPS, CentOS 9): установка модуля и баз, переменные в лог и заголовки, проверка и типичные ошибки.

Как включить GeoIP в Nginx: переменные для логов и заголовков

Требования

  • BitrixVM 9+ на CentOS Stream 9+
  • Nginx из официального репозитория nginx.org
  • Понимание структуры конфигов Nginx в BitrixVM (nginx + httpd)

Как включить GeoIP в Nginx: переменные для логов и заголовков

Запрос «как включить GeoIP в Nginx и получить переменные для логов и заголовков» чаще всего всплывает у тех, кто ведёт аудит трафика на VPS: нужно видеть страну/город в access.log или прокинуть страну в приложение (например, Bitrix за Apache). В конце будет рабочая конфигурация для BitrixVM (nginx+httpd), проверка, и список типичных проблем.


В чём проблема

Симптом обычно один из этих:

  1. В конфиг добавили geoip_country / geoip_city, а Nginx на перезагрузке падает:
nginx: [emerg] unknown directive "geoip_country" in /etc/nginx/nginx.conf:XX
  1. Или модуль подключили, но переменные пустые — в логах вместо страны -:
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;

Диапазон подставьте свой (подсеть балансировщика/прокси).


Проверка результата

  1. Проверяем синтаксис конфига:
nginx -t

Ожидаемо:

syntax is ok
test is successful
  1. Перезагружаем:
systemctl reload nginx
  1. Дёргаем сайт и смотрим лог:
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 — это в основном “наследие”, которое живёт только если у вас уже есть источник баз.

0 просмотров

Комментарии

Загрузка комментариев...
Пока нет комментариев. Будьте первым!