У меня есть сайт с nginx, действующий как обратный прокси-сервер для apache 2.2, на котором запущен php. С точки зрения apache и php IP-адрес всех запросов является сервером nginx. Я бы хотел, чтобы php увидел тот же удаленный IP-адрес, что и nginx.
Nginx устанавливает заголовок X-Real-IP, который содержит удаленный IP-адрес, который видит nginx. Я попытался сделать что-то подобное в apache conf:
SetEnvIf ^X-Real-IP$ "(.+)" REMOTE_ADDR=$1
Я надеялся, что я смогу установить переменную среды REMOTE_ADDR, и когда наконец-то вызывается php, он увидит удаленный IP-адрес, который видит nginx. Я думаю, что PHP-код делает это:
$_SERVER['REMOTE_ADDR']
Во всяком случае, это не работает. Есть идеи? Не можете ли вы установить REMOTE_ADDR в конфигурационный файл apache? Благодарю.
Не уверен, что REMOTE_ADDR
можно изменить таким образом …
На самом деле вам может потребоваться установить / включить другой модуль Apache, например mod_rpaf
(цитирование) :
Он изменяет удаленный адрес клиента, видимый для других модулей Apache, когда выполняются два условия.
Первое условие заключается в том, что удаленный клиент фактически является прокси-сервером, который определен в httpd.conf.
Во-вторых, если есть входящий заголовок X-Forwarded-For, а прокси-сервер находится в списке известных прокси, он берет последний IP-адрес из входящего заголовка X-Forwarded-For и изменяет удаленный адрес клиента в структуре запроса.
Он также принимает входящий заголовок X-Host и соответственно обновляет настройки виртуального хоста.
Для mod_proxy Apache2 он принимает заголовок X-Forwared-Host и обновляет виртуальные хосты
Вот блог-сообщение об этом: прокси-сервер Nginx для Apache – доступ к удаленному IP-адресу хоста с помощью mod_praf
Обновление: исходная ссылка не работает прямо сейчас, но она также доступна как пакет debian: apt-get install libapache2-mod-rpaf
Я решил это использовать mod_remoteip для Apache. mod_remoteip для Apache 2.5, но благодаря этому парню вы можете использовать его и на Apache 2.2.x.
Загрузите mod_remoteip.c из https://gist.github.com/1042237 и скомпилируйте его с помощью
apxs -i -a -c mod_remoteip.c
Это должно создать копию mod_remoteip.so в каталоге модулей. apxs также добавят директиву LoadModule в ваш httpd.conf для вновь созданного модуля.
Откройте httpd.conf и проверьте, существует ли директива LoadModule для mod_remoteip
LoadModule remoteip_module modules/mod_remoteip.so
Добавить директиву RemoteIPHeader в httpd.conf
RemoteIPHeader X-Forwarded-For
Эта директива будет давать команду mod_remoteip использовать значение X-Forwarded-For из nginx как remote_addr. Вместо этого вы можете использовать X-Real-IP:
RemoteIPHeader X-Real-IP
Перезапустите Apache. Если вы установили заголовки прокси в nginx, это будет работать как шарм, а remote_addr в Apache будет правильным
# nginx conf proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Вы можете попробовать этот простой PHP-модуль
https://github.com/yohgaki/realip
Он просто перезаписывает $ _SERVER ['REMOTE_ADDR'] с X-Forwarded-For или X-Real-IP любым заголовком, который вам нравится. Вы можете сделать это со многими разными способами, но я просто хотел бы сделать это как PHP-модуль. Поэтому я написал это.
Я не знаю, можно ли манипулировать REMOTE_ADDR – возможно, это невозможно, но вы должны уметь захватить заголовок X-Real-IP в PHP через что-то вроде
$ _SERVER [ "HTTP_X_Real_IP"]
или аналогичные – проверьте правильность обозначений phpinfo()
.
Кроме того, переменные окружения Apache, установленные в .htaccess
должны быть видны в PHP.
Apache (требуется модуль mod_headers):
SetEnvIf X-Real-IP "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFF_CLIENT_IP=$1 RequestHeader set REMOTE_ADDR %{XFF_CLIENT_IP}e
REF для SetEnvIf RegEx: https://stackoverflow.com/a/10346093
Работает также, но не проверяет ввод как IP:
SetEnvIf X-Real-IP "^(.*)" XFF_CLIENT_IP=$1 RequestHeader set REMOTE_ADDR %{XFF_CLIENT_IP}e
В PHP:
$_SERVER["HTTP_REMOTE_ADDR"]
-или-
$_SERVER["REMOTE_ADDR"]
Не требуются неосновные модули Apache
mod_rpaf (sudo apt-get install libapache2-mod-rpaf)
разрешил все проблемы, и REMOTE_ADDRR теперь выглядит нормально! ..
Off манжеты .. но вы могли бы передать заголовок X-Real-IP как переменную в php, используя некоторую переписывающую магию ..? Не может htaccess делать материал с информацией заголовка, прежде чем он вызывает PHP?
Вероятно, вы захотите использовать это на самом деле: http://httpd.apache.org/docs/2.3/mod/mod_remoteip.html . Обладает множеством функций и поддерживается самими апачами.
Изменить: я имел в виду предложение mod_rpaf выше.