【问题标题】:How can I set REMOTE_ADDR in apache before php is invoked?如何在调用 php 之前在 apache 中设置 REMOTE_ADDR?
【发布时间】:2011-01-20 15:45:55
【问题描述】:

我有一个网站设置了 nginx 作为运行 php 的 apache 2.2 的反向代理。从 apache 和 php 的角度来看,所有请求的 IP 地址都是 nginx 服务器。我希望 php 看到与 nginx 看到的相同的远程 IP。

Nginx 设置一个头 X-Real-IP ,其中包含 nginx 看到的远程 IP。我尝试在 apache conf 中做这样的事情:

SetEnvIf ^X-Real-IP$ "(.+)" REMOTE_ADDR=$1

我希望我可以设置 REMOTE_ADDR 环境变量,当 php 最终被调用时,它会看到 nginx 看到的远程 IP。我认为php代码是这样做的:

$_SERVER['REMOTE_ADDR']

无论如何,这是行不通的。不能在apache配置文件中设置REMOTE_ADDR吗?

【问题讨论】:

    标签: php apache


    【解决方案1】:

    不确定REMOTE_ADDR 是否可以这样更改...


    实际上,您可能需要安装/启用另一个 Apache 模块,例如 mod_rpaf (quoting)

    它改变了远程地址 客户端对其他 Apache 模块可见 当满足两个条件时。
    第一个条件是遥控器 客户端实际上是一个代理,即 在 httpd.conf 中定义。
    其次,如果 有一个传入的 X-Forwarded-For 标头和代理在它的列表中 已知代理的最后一个 IP 从传入的 X-Forwarded-For 标头并更改远程地址 请求中的客户端 结构体。
    它还需要 传入 X-Host 标头并更新 相应的虚拟主机设置。
    对于 Apache2 mod_proxy,它需要 X-Forwared-Host 标头并更新 虚拟主机

    这是一篇关于此的博文:Nginx proxy to Apache - access remote host IP address using mod_praf

    更新:原始链接现在无法使用,但它也可以作为 debian 包提供:apt-get install libapache2-mod-rpaf

    【讨论】:

    • +1 不错!很高兴知道这一点。尽管该模块的名称听起来像是有人用卡通语言打了别人的脸颊:)
    • 附带说明:我从未听说过该模块;不确定它是否得到很好的支持/稳定/维护/ ...;; 不,这个名字听起来很有趣^^不一定是坏事
    • 我敢肯定,鉴于一堆“聪明聪明”的漫画,我可以在某个地方找到暴力场景中使用的词。举例说明:pekkagaiser.com/stuff/cleversmart.jpg(是德语,但没关系。)
    • @Pekka : 在法语中,我们有时(实际上是几年前) 说“Et paaaffff le chien”——“and paf the dog”^^; ;; @Russell:很高兴知道!我自己有一个 apache 服务器,将 nginx 用作反向代理,我遇到了同样的问题 (但通过修补我的 PHP 脚本“解决了”它)
    • mod_rpaf 已被 Apache 的内置 mod_remoteip 取代。
    【解决方案2】:

    我已经使用 Apache 的 mod_remoteip 解决了这个问题。 mod_remoteip 适用于 Apache 2.5,但感谢this guy,您也可以在 Apache 2.2.x 上使用它。

    https://gist.github.com/1042237下载mod_remoteip.c并用

    编译
    apxs -i -a -c mod_remoteip.c
    

    这应该在模块目录中创建 mod_remoteip.so 副本。 apxs 还将在您的 httpd.conf 中为新创建的模块添加 LoadModule 指令。

    打开 httpd.conf 并检查 mod_remoteip 的 LoadModule 指令是否存在

    LoadModule remoteip_module    modules/mod_remoteip.so
    

    在 httpd.conf 中添加 RemoteIPHeader 指令

    RemoteIPHeader X-Forwarded-For
    

    该指令将指示 mod_remoteip 使用来自 nginx 的 X-Forwarded-For 值作为 remote_addr。您也可以改用 X-Real-IP:

    RemoteIPHeader X-Real-IP
    

    重新启动 Apache。如果您在 nginx 中设置了代理标头,它将像魅力一样工作,并且 Apache 中的 remote_addr 将是正确的

    # nginx conf    
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    

    【讨论】:

    • 但是使用mod_rewrite好像有问题。重写的 URL 不会有正确的 remote_addr :(
    • mod_remoteip 有一个缺陷,它不适用于 mod_rewrite,即在重写的 URL 上,您仍然会得到 127.0.0.1。所以最后,我找到的唯一正确的解决方案是 mod_rpaf。编译它并按照我为 mod_remoteip 描述的类似方式安装它
    【解决方案3】:

    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
    

    SetEnvIf 正则表达式的引用: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 模块

    【讨论】:

    • 不设置 REMOTE_ADDR,只设置 HTTP_REMOTE_ADDR (apache 2.2)。
    • 极好的解决方案!谢谢!
    【解决方案4】:

    你可以试试这个简单的 PHP 模块

    https://github.com/yohgaki/realip

    它只是用 X-Forwarded-For 或 X-Real-IP 重写 $_SERVER['REMOTE_ADDR'] 任何你喜欢的标题。您可以使用许多不同的方法来完成此操作,但我只想将其作为 PHP 模块来完成。所以我写了它。

    【讨论】:

      【解决方案5】:

      我不知道 REMOTE_ADDR 是否可以被操纵 - 可能它不能 - 但你应该能够通过类似的方式在 PHP 中获取 X-Real-IP 标头

      $_SERVER["HTTP_X_Real_IP"]

      或类似的 - 检查 phpinfo() 以获取正确的符号。

      另外,.htaccess 中设置的 Apache 环境变量应该在 PHP 中可见。

      【讨论】:

      • 更正一次,必须是$_SERVER["HTTP_X_REAL_IP"],区分大小写
      【解决方案6】:

      mod_rpaf (sudo apt-get install libapache2-mod-rpaf)

      解决了所有问题,REMOTE_ADDRR 现在看起来不错!..

      【讨论】:

        【解决方案7】:

        袖手旁观..但是您能否使用一些重写魔术将标头 X-Real-IP 作为变量传递给 php..? htaccess 不能在调用 PHP 之前处理头信息吗?

        【讨论】:

          【解决方案8】:

          您可能想实际使用它:http://httpd.apache.org/docs/2.3/mod/mod_remoteip.html。有更多的功能,由 apache 自己维护。

          编辑:我指的是上面的 mod_rpaf 建议。

          【讨论】:

            【解决方案9】:

            在 Apache 2.4 中,您可以定义使用哪个字段。 https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html

            【讨论】:

              【解决方案10】:

              我在 Apache 2.4 中使用 linux 语句

              sudo a2enmod remoteip
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-01-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-01-14
                • 1970-01-01
                • 1970-01-01
                • 2015-06-05
                相关资源
                最近更新 更多