Как я боролся с неверной переменной REMOTE_ADDR

В общем всё начиналось как обычно, поставил сервер Apache как back-end (задний сервер) и Nginx как front-end (передний сервер), он же играл роль прокси-сервера для апача. Разумеется надо заменять переменную окружения Apache REMOTE_ADDR (удалённый адрес), в которой должен находится IP адрес клиента делающего запросы к апачу. Надо лишь подключить и настроить, популярный для этих целей, модуль mod_rpaf (он же rpaf_module) для сервера Apache, что бы он брал определённый заголовок из запроса (обычно это X-Forwarded-For) и его значение записывал в переменную REMOTE_ADDR.

В общем как долго я не мучился, так и не получилось заставить этот rpaf_module работать нормально. Всё было подключено и настроено, но переменная REMOTE_ADDR содержала в себе адрес веб-сервера а не адрес клиента.

Для просмотра всех переменных окружения веб-сервера и подключенных модулей Apache удобно использовать сводную информацию получаемую от функции phpinfo(). Для просмотра всех подключенных модулей apache есть утилита apache2ctl.

# получить список только статических модулей
apache2ctl -l
# получить список обоих (статических и общих/shared) модулей
apache2ctl -M

Настройка apache модуля rpaf

Вообще для настройки модуля  rpaf_module много делать не нужно. Во-первых подключаем этот самый rpaf_module директивой LoadModule примерно так:

LoadModule rpaf_module modules/mod_rpaf-2.0.so

Открываем или создаём файл rpaf.conf и в нём указываем следующее:

<IfModule rpaf_module>
#Включение модуля
RPAFenable On
# Определяем IP адреса веб-сервера
RPAFproxy_ips 127.0.0.1 xx.xx.xx.xx yy.yy.yy.yy
</IfModule>

Где xx.xx.xx.xx и yy.yy.yy.yy — IP адреса вашего сервера. Каждый IP адрес пишется через пробел. Там есть и пара других директив, но он нам не нужны. Если они есть, то можно их или закомментировать или просто удалить.

На этом, по большому счёту всё, перезапускаем апач.

Настройки Nginx

В nginx могут потребоваться дополнительные настройки. Если прокси сервер не добавляет к запросам заголовки X-Forwarded-For, то надо заставить его это делать.

В nginx внутри блока http{} должны быть указаны строки:

proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for

Или вот так, чтоб наверняка:

proxy_set_header X-Real-IP  $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header  X-Server-Address  $server_addr;
proxy_set_header Host $host;

После изменений в файле конфигурации перезапускаем и Nginx.

По сути это всё, что надо сделать для правильного REMOTE_ADDR, если не вышло, и там не то, что нужно значит нужно искать другой путь, всегда есть другой путь.

Я же, как дурак, ещё долго мучился и менял конфигурацию модуля mod_rpaf в надежде заставить его работать не зная о том, что ему есть хорошие альтернативы.

Альтернативы модулю rpaf

mod_realip — это модуль для Apache 1.3 для изменения адреса прокси-сервера на адрес клиента, переданный прокси-сервером в заголовках «X-Real-IP» или «X-Forwarded-For». Предназначен для использования на бэкендах при реверсном проксировании.

В общем для подобных целей смены переменной REMOTE_ADDR есть ещё, как минимум, 2 других модуля: remoteip_module и realip_module. Первый из них — remoteip_module вообще обычно идёт в комплекте с веб-сервером Apache «из коробки», т.е. как бы стандартный. Его и будем использовать.

Отключаем rpaf_mod и подключаем remoteip_module.

Настройка remoteip_module

Ну сперва убедимся, что он у нас есть, откроем папку со всеми модулями и посмотрим, для Linux Ubuntu это /usr/lib/apache2/modules.

Подключим его:

LoadModule remoteip_module /usr/lib/apache2/modules/mod_remoteip.so

И теперь быстро настроим. Открываем файл remoteip.conf и добавляем туда следующее:

<IfModule remoteip_module>
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1 xx.xx.xx.xx yy.yy.yy.yy
</IfModule>

Директива RemoteIPHeader устанавливает название заголовка из которого будет браться значение для установки переменной REMOTE_ADDR. В параметрах директивы RemoteIPInternalProxy прописываем IP адреса веб-сервера.

Перезапускаем апач, убеждаемся в том, что модуль remoteip_module подключен и работает, теперь в переменной REMOTE_ADDR должен быть адрес клиента а не сервера. Разумеется прокси-сервер должен передавать заголовок X-Forwarded-For с нужным адресом, это мы уже проходили.

Логи apache могут работать немного неправильно, в этом случае открываем файл конфигурации апача (/etc/apache2/apache2.conf) и меняем это:

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

На это:

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

Или это:

LogFormat "%h %{host}i %l %u %D %T %{pid}P %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

На это:

LogFormat "%a %{host}i %l %u %D %T %{pid}P %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

Ну в общем там можно разобраться, форматы логов разные.

Вывод

Исходя из своих наблюдений сделал вывод, что для замены заголовков для Apache 2.2 подходит модуль rpaf, для версии 2.4 он никак не подходит и нужен модуль remoteip.

Поделиться!
Tags: , , , , ,

49.7MB | MySQL:52 | 0,289sec