Установите REMOTE_ADDR в X-Forwarded-For в apache

В ситуации, когда Apache сидит за обратным прокси (например, Squid), переменная среды cgi REMOTE_ADDR получает адрес прокси, а не клиент.

Однако прокси установит заголовок с именем X-Forwarded-For, чтобы содержать исходный IP-адрес клиента, чтобы Apache мог его видеть.

Вопрос в том, как мы можем заставить Apache заменить REMOTE_ADDR на значение в заголовке X-Forwarded-For, чтобы все веб-приложения прозрачно отображали правильный адрес?

Ответ 2

Обратите внимание, что заголовок X-Forwarded-For может содержать список IP-адресов, если запрос прошел более одного прокси-сервера. В этом случае вам обычно нужен самый правый IP-адрес. Вы можете извлечь это с помощью SetEnvIf:

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

Обратите внимание на использование $1, чтобы установить переменную среды XFFCLIENTIP для хранения содержимого первой группы в регулярном выражении (в круглых скобках).

Затем вы можете использовать значение переменной окружения для установки заголовков (или использовать его в форматах журнала Apache, чтобы журналы содержали фактический IP-адрес клиента).

Ответ 3

В дополнение к mod_rpaf, как упоминалось ранее, кажется, что mod_extract_forwarded также выполнит эту функцию.

Одно из преимуществ mod_extract_forwarded заключается в том, что он доступен из EPEL для серверов RHEL/CentOS, тогда как mod_rpaf нет.

Похоже, что ни один из этих двух модулей не позволяет вам переадресовывать всю подсеть прокси-серверов, поэтому люди CloudFlare создали свой собственный плагин: mod_cloudflare, который, следует отметить, не является инструментом общего назначения, как два других; он содержит жесткий список подсети CloudFlare.

Ответ 4

Да, мы можем это сделать.

Просто добавьте auto_prepend_file в ваш PHP.ini, например auto_prepend_file = "c:/prepend.php" и в этом файле добавьте это:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

Вам нужна MOD_REMOTEIP в ширине apache RemoteIPHeader X-Real-IP.

Приветствия,

Guiremach

Ответ 5

К сожалению,

на момент написания этой статьи ни один из backports и forks на freshports.org, people.apache.org или gist.github.com не работал. Все они были основаны на ранней альфа-версии apache httpd 2.3, которая не была совместима с текущими версиями 2.2 и 2.4.

Итак, после нескольких часов тратить время, пытаясь настроить backports, чтобы создать реальный рабочий для httpd 2.2, я решил перейти на httpd 2.4. В пределах httpd 2.4 mod_remoteip работает плавно, даже если балансировщик нагрузки имеет постоянные постоянные соединения, которые он использует для прокси-запросов с разных фактических IP-адресов клиента на бэкэнд. Я не уверен, могут ли другие модули справиться с этой ситуацией (изменение IP-адресов клиента по каждому запросу в одном и том же соединении).

Ответ 6

Помните, что это значение может быть подделано. См. http://blog.c22.cc/2011/04/22/surveymonkey-ip-spoofing/ для примера в реальной жизни с последствиями сценариев Cross-Site Scripting.

Ответ 7

Вы можете установить модуль mod_extract_forwarded и установить для параметра MEFaccept.

Ответ 8

В настоящее время Apache модуль Mod_remoteip является рекомендуемым способом сделать это; rpaf не был надежно поддержан и может вызвать проблемы.

Ответ 9

Мне нравится этот пост, он был очень полезным. Я нахожусь в почти 99% моего случая использования. Мне нужно выяснить исходный IP-адрес клиента, который связывается из Интернета через AWS Loadbalancer с EC2 с веб-сервером Apache. Мой ReWriteRule пока не работает (см. Код ниже). Что я должен использовать вместо REMOTE_ADDR, чтобы получить IP-адрес клиента?

Что у меня так далеко в моем журнале:

aaa.aaa.aaa.aaa bbb.bbb.bbb.bbb - - [21/May/2019:14:36:38 +0200] "GET /maintenance/index.html HTTP/1.1" 200 1187 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36

Где aaa.aaa.aaa.aaa указывает мой клиентский IP, а bbb.bbb.bbb.bbb - это IP-адрес Loadbalancer

В моем httpd vHost config у меня есть:

SetEnvIf X-Forwarded-For "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFFCLIENTIP=$1
    RemoteIPHeader X-Real-IP
    # Redirect all request to a 503 return code when in maintenance mode
    UseCanonicalName On
    ErrorDocument 503 /maintenance/index.html
    RewriteEngine on
    RewriteMap exceptions /appli/sutomer/apps/fas/maintenance/exceptions.map

    # Allow Individual IP addresses past maintenance page
    RewriteCond ${exceptions:%{REMOTE_ADDR}} =OK
    RewriteRule ^ - [L]

Где мой файл exceptions.map содержит:

aaa.aaa.aaa.aaa OK