【问题标题】:Set correct REMOTE_ADDR in PHP-FPM called from Apache在从 Apache 调用的 PHP-FPM 中设置正确的 REMOTE_ADDR
【发布时间】:2020-02-07 16:32:30
【问题描述】:

我们想在我们的 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 replace REMOTE_ADDR with X-Forwarded-For

【问题讨论】:

    标签: apache nginx ip fastcgi php


    【解决方案1】:

    通过在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];
        }
      }
    }
    

    【讨论】:

    • 我知道那是旧的,但是这家伙储备金,哇,谢谢,这终于解决了我的任何问题(尝试了 +10 个解决方案,+4 个月)
    • 非常好的方法。使用 apache 2.4 可以使用 apache config 提供更简单的解决方案,请参阅我的答案。
    • 我正在使用$_SERVER[$serverVar] = explode(',', $_SERVER[$header], 2)[0];,因为有时中间代理会向列表中添加更多项目。
    【解决方案2】:

    如果您想在日志中查看真实 IP,请在 access.format 指令中使用 %{REMOTE_ADDR}。在您的池中php-fpm.conf

    【讨论】:

    • 正确的格式是%{REMOTE_ADDR}e 而不是%{REMOTE_ADDR}
    【解决方案3】:

    在 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。

    【讨论】:

      【解决方案4】:

      在 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

      【讨论】:

      • 我们在 Apache 服务器而不是 Nginx 服务器上需要这个。
      • 问题不在于 apache 本身在代理之后。我们已经有了 mod_rpaf 并且 apache 使用了正确的 IP(例如在 apache 日志中)。问题是这个 apache 使用 fastCGI+PHP-FPM 来处理 PHP 请求。它在没有代理的情况下无法工作,因为 PHP 从 apache(即 localhost)获得了请求。我刚才提到了代理,因为我们已经有了这些可以使用的标头。
      【解决方案5】:

      由于我只是在这上面花了几个小时,我想指出 mod_rpaf 在使用 mod_proxy + mod_proxy_fcgi 而不是 mod_fcgi 时似乎无法正常工作(至少在 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) 中的 %h 替换为 %a 即可]

      【讨论】:

        猜你喜欢
        • 2011-01-20
        • 1970-01-01
        • 2023-03-10
        • 2014-05-21
        • 1970-01-01
        • 2011-01-15
        • 2013-09-03
        • 2014-07-20
        • 2015-08-14
        相关资源
        最近更新 更多