[英]Set correct REMOTE_ADDR in PHP-FPM called from Apache
我們想在我們的 Apache 服務器上從 mod_php 切換到 fastCGI + PHP-FPM。
除了一件事,我們已經准備好一切並開始工作:
我們的 $_SERVER['REMOTE_ADDR'] 中的值總是 127.0.0.1 而不是客戶端的 IP。 有什么辦法可以配置服務器將此變量設置為客戶端真實IP?
我們在 X-Forwarded-For 標頭中有客戶端真實 IP(從代理傳遞)
基本上我們需要 Apache 替代 nginx 配置:
fastcgi_param REMOTE_ADDR $http_x_forwarded_for;
(如此處所述, Nginx 將 REMOTE_ADDR 替換為 X-Forwarded-For )
通過向 php.ini 添加指令解決:
auto_prepend_file = /etc/php5/rpaf.php
它允許執行這個簡單的 PHP 腳本來規范標頭:
<?php
$trustedProxies = array(
'127.0.0.1'
);
$remote = $_SERVER['REMOTE_ADDR'];
$allowedHeaders = array(
'HTTP_X_FORWARDED_FOR' => 'REMOTE_ADDR',
'HTTP_X_REAL_IP' => 'REMOTE_HOST',
'HTTP_X_FORWARDED_PORT' => 'REMOTE_PORT',
'HTTP_X_FORWARDED_HTTPS' => 'HTTPS',
'HTTP_X_FORWARDED_SERVER_ADDR' => 'SERVER_ADDR',
'HTTP_X_FORWARDED_SERVER_NAME' => 'SERVER_NAME',
'HTTP_X_FORWARDED_SERVER_PORT' => 'SERVER_PORT',
);
if(in_array($remote, $trustedProxies)) {
foreach($allowedHeaders as $header => $serverVar) {
if(isSet($_SERVER[$header])) {
if(isSet($_SERVER[$serverVar])) {
$_SERVER["ORIGINAL_$serverVar"] = $_SERVER[$serverVar];
}
$_SERVER[$serverVar] = $_SERVER[$header];
}
}
}
如果您想在日志中查看真實 IP,請在access.format
指令中使用%{REMOTE_ADDR}
。 在池的php-fpm.conf
中。
在 nginx 配置中設置它。
# Set the client remote address to the one sent in the X_FORWARDED_FOR header from trusted addresses.
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
來源: http : //nginx.org/en/docs/http/ngx_http_realip_module.html
——
Apache 更新
對於 Apache,安裝模塊mod_rpaf
並配置它。
LoadModule rpaf_module modules/mod_rpaf.so
RPAF_Enable On
RPAF_ProxyIPs 127.0.0.1 10.0.0.0/24
RPAF_SetHostName On
RPAF_SetHTTPS On
RPAF_SetPort On
RPAF_ForbidIfNotProxy Off
由於我只花了幾個小時,我想指出當使用 mod_proxy + mod_proxy_fcgi 而不是 mod_fcgi 時 mod_rpaf 似乎無法正常工作(至少在 Debian Jessie 上)
雖然當 mod_rpaf 和負載均衡器都正確配置時 mod_rpaf 確實會修復 apache 訪問日志,但遺憾的是它不會修復 PHP 的 $_SERVER['REMOTE_ADDR'] 變量。
有些人建議使用以下方法手動覆蓋 REMOTE_ADDR:
SetEnvIf X-Real-IP "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" REMOTE_ADDR=$1
RequestHeader set REMOTE-ADDR %{REMOTE_ADDR}e env=REMOTE_ADDR
雖然您可以通過這種方式向 $_SERVER(帶和不帶 HTTP 前綴)添加自定義條目,但它不適用於 REMOTE_ADDR ...
另一方面,使用 mod_remoteip 將正確的 ip 傳遞給 $_SERVER['REMOTE_ADDR']
,但似乎 apache 訪問日志再次顯示負載平衡器 ip ......
[編輯:沒關系,在訪問日志格式定義 (apache2.conf) 中用 %a 替換 %h 並且它有效]
使用 apache 2.4,您可以使用 apache 的mod_remoteip
模塊。 它將在 apache 日志中設置預期的客戶端 IP,並將該信息轉發到 php-fpm,而無需在 php-fpm 中進行任何更改。 使用官方httpd
和php-fpm
docker 鏡像進行測試。
這是您的httpd.conf
的示例配置部分:
LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By
# 0.0.0.0/0 is not accepted
RemoteIPInternalProxy 172.0.0.0/8
其他提到的mod_rpaf
在 apache 2.4 中不再可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.