Настройка реального IP в apache для bitrix

Введение

Типовая стандартная схема: битрикс-окружение и 127.0.0.1 в логах apache. В данной заметке будет рассказано, как настроить в логах apache реальный клиентский IP-адрес.

По умолчанию, если развернуть окружение битрикс (bitrix-env), в логах апача будет 127.0.0.1 – это адрес nginx, с которого приходит запрос. Для того, чтобы в апач передавался клиентский IP-адрес, nginx вместе с запросом должен также передавать заголовки X-Forwarded-For и X-Real-IP.

X-Forwarded-For содержит в себе цепочку IP-адресов: если клиент со своим реальным адресом проходит через 1 прокси, 2 прокси, n прокси, то все эти адреса “должны” быть записаны в заголовке X-Forwarded-For, который передается для конечного сервера, а тот уже должен извлекать самый первый IP-адрес, который будет являться клиентским.

X-Real-IP же является заголовком, который содержит только клиентский адрес.

Nginx вышеописанные заголовки принимает, в X-Forwarded-For добавляет свою информацию и проксирует уже в сторону apache, где необходимо настроить корректный прием, т.е. получение реального клиентского IP-адреса.

Настройка httpd

Например, вот такие заголовки “пришли” от Nginx, т.е. были отправлены вместе с http-запросом:

X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1 
X-Real-IP: 123.123.123.123

123.123.123.123 – клиентский IP-адрес, 192.168.2.1 – какой-то промежуточный прокси, а 127.0.0.1 – уже сам nginx (локалхост, т.к. оба веб-сервера находятся на одной машине).

На самом деле апач из коробки битрикс-окружения уже умеет извлекать клиентский IP-адрес, для этого используется модуль mod_remoteip в версиях 2.4 и выше. В версии 2.2 использовался модуль mod_rpaf, сейчас его использовать уже не рекомендуется.

Для проверки, что модуль установлен, необходимо проверить список модулей:

httpd -M | grep -i remote

remoteip_module (shared)

И проверить конфигурационный файл по пути /etc/httpd/bx/conf/mod_rpaf.conf. Не смотря на то, что файл называется также, как и старый depracated-модуль rpaf, внутри используются директивы модуля mod_remoteip. Если используется кастомное окружение, можно назвать файлы более корректно. И вот что находится в файле:

RemoteIPHeader X-Real-IP
RemoteIPInternalProxy 127.0.0.1
  • Директива RemoteIPHeader – в ней указывается значение X-REAL-IP с реальным IP, т.е. переменная remote_addr, которая есть в httpd, будет получать значение как раз из этого заголовка.
  • Директива RemoteIPInternalProxy указывает, от каких серверов можно принимать заголовок с клиентским IP. Стоит обратить внимание, что RemoteIPInternalProxy применима только к адресам частных подсетей – 10.0.0.0/8, 172.16/12, 192.168/16, 169.254/16 и127/8. Если нужно указать вышестоящие сервера с белыми адресами, то необходимо использовать директиву RemoteIPTrustedProxy.

Получается, что в битрикс-окружении уже всё настроено, но в логах почему-то всё равно 127.0.0.1. Причиной этого является то, что лог-файлы по умолчанию имеют следующий формат:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

И вот тут-то значение %h и содержит в себе 127.0.0.1. Поэтому LogFormat необходимо привести к следующему виду:

LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

В примере выше %h меняется на %a и в логах появляется реальный адрес клиента и ради замены одного символа написано столько текста :)

После этого необходимо перечитать конфигурацию httpd для вступления в силу новых параметров логирования и проверять: в логах апача теперь фигурирует реальный IP-адрес пользователя.

Также есть ещё вариант с явным добавлением значения из заголовка X-Forwarded-For:

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

Но в этом случае может быть следующий нюанс: в логах httpd будет цепочка адресов, если клиент проходил через несколько прокси. Это всё потому, что в X-Forwarded-For содержится несколько IP-адресов. Например:

192.168.20.197 192.168.20.12 - admin [29/Oct/2020:18:31:43 +0300] "GET / ...

В каких-то случаях такой формат может не подойти и может возникнуть желание использовать только один крайний левый адрес, который идёт первым по счёту, т.е. клиентский. Для этого можно воспользоваться регулярным выражением. В конфиге httpd.conf:

# set env
SetEnvIf X-Forwarded-For "^(\d{1,3}+.\d{1,3}+.\d{1,3}+.\d{1,3}+).*" XFFCLIENTIP=$1

LogFormat "%{XFFCLIENTIP}e %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

Задаётся регулярное выражение, под которое попадают все значения в виде IP-адресов из заголовка X-Forwarded-For. А при присвоении значения в переменную XFFCLIENTIP берётся только первое вхождение IP-адреса, т.е. клиентский.

И потом в конфиге виртуального хоста указать тип используемого лога (как обычно, по умолчанию это уже есть) и обязательно указать в конце, что используется значение из переменной:

CustomLog /dev/stdout combined env=XFFCLIENTIP

С подробным форматом лога апач можно ознакомиться в документации по ссылке ниже.

Используемые источники:

Понравилась статья? Поделиться с друзьями:
Комментарии: 2
  1. Дмитрий

    Добрый день!
    Делал как у вас в статье.
    При замене %h на %a, в журнале Битрикс ничего не поменялось.
    Подскажите, где нужно править формат лога, я делал это в :
    /etc/httpd/conf/default.conf

    1. admin (автор)

      Добрый день! Про журнал битрикса не подскажу, т.к. админкой почти не пользуюсь. В статье рассказано про формат логов в апаче, которые хранятся на сервере.

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: