簡體   English   中英

在從 Apache 調用的 PHP-FPM 中設置正確的 REMOTE_ADDR

[英]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

來源: https : //github.com/gnif/mod_rpaf

由於我只花了幾個小時,我想指出當使用 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 中進行任何更改。 使用官方httpdphp-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM