Введение
Типовая стандартная схема: битрикс-окружение и 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
С подробным форматом лога апач можно ознакомиться в документации по ссылке ниже.
Добрый день!
Делал как у вас в статье.
При замене %h на %a, в журнале Битрикс ничего не поменялось.
Подскажите, где нужно править формат лога, я делал это в :
/etc/httpd/conf/default.conf
Добрый день! Про журнал битрикса не подскажу, т.к. админкой почти не пользуюсь. В статье рассказано про формат логов в апаче, которые хранятся на сервере.