如何在调用 php 之前在 apache 中设置 REMOTE_ADDR
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2328225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set REMOTE_ADDR in apache before php is invoked
提问by Russell Neufeld
I have a website set up with nginx acting as a reverse proxy to apache 2.2, which is running php. From apache and php's perspective the IP address of all requests is the nginx server. I'd like php to see the same remote IP that nginx sees.
我有一个使用 nginx 设置的网站作为 apache 2.2 的反向代理,它运行 php。从 apache 和 php 的角度来看,所有请求的 IP 地址都是 nginx 服务器。我希望 php 看到与 nginx 看到的相同的远程 IP。
Nginx sets a header X-Real-IP which contains the remote IP that nginx sees. I tried doing something like this in the apache conf:
Nginx 设置了一个头 X-Real-IP,其中包含 nginx 看到的远程 IP。我尝试在 apache conf 中做这样的事情:
SetEnvIf ^X-Real-IP$ "(.+)" REMOTE_ADDR=
My hope was that I could set the REMOTE_ADDR environment variable and when php finally gets invoked, it would see the remote IP that nginx sees. I think the php code is doing this:
我希望我可以设置 REMOTE_ADDR 环境变量,当 php 最终被调用时,它会看到 nginx 看到的远程 IP。我认为 php 代码是这样做的:
$_SERVER['REMOTE_ADDR']
Anyway, this isn't working. Any ideas? Can you not set REMOTE_ADDR in the apache config file? Thanks.
无论如何,这是行不通的。有任何想法吗?你不能在 apache 配置文件中设置 REMOTE_ADDR 吗?谢谢。
回答by Pascal MARTIN
Not sure whether REMOTE_ADDRcan be changed that way...
不知道REMOTE_ADDR能不能改成这样...
Actually, you might need to install / enable another Apache module, like mod_rpaf(quoting):
实际上,您可能需要安装/启用另一个 Apache 模块,例如(引用):mod_rpaf
It changes the remote address of the client visible to other Apache modules when two conditions are satisfied.
First condition is that the remote client is actually a proxy that is defined in httpd.conf.
Secondly if there is an incoming X-Forwarded-For header and the proxy is in it's list of known proxies it takes the last IP from the incoming X-Forwarded-For header and changes the remote address of the client in the request structure.
It also takes the incoming X-Host header and updates the virtualhost settings accordingly.
For Apache2 mod_proxy it takes the X-Forwared-Host header and updates the virtualhosts
当满足两个条件时,它会更改其他 Apache 模块可见的客户端的远程地址。
第一个条件是远程客户端实际上是在 httpd.conf 中定义的代理。
其次,如果有一个传入的 X-Forwarded-For 标头并且代理在它的已知代理列表中,它会从传入的 X-Forwarded-For 标头中获取最后一个 IP 并更改请求结构中客户端的远程地址。
它还获取传入的 X-Host 标头并相应地更新虚拟主机设置。
对于 Apache2 mod_proxy,它采用 X-Forwared-Host 标头并更新虚拟主机
Here's a blog-post about that : Nginx proxy to Apache - access remote host IP address using mod_praf
这是一篇关于此的博客文章:Nginx 代理到 Apache - 使用 mod_praf 访问远程主机 IP 地址
Update: original link not working right now, but it is available also as a debian package: apt-get install libapache2-mod-rpaf
更新:原始链接现在不起作用,但它也可以作为 debian 包使用: apt-get install libapache2-mod-rpaf
回答by mileusna
I have solved this using mod_remoteip for Apache. mod_remoteip is for Apache 2.5 but thanks to this guyyou can use it on Apache 2.2.x as well.
我已经使用 mod_remoteip for Apache 解决了这个问题。mod_remoteip 适用于 Apache 2.5,但多亏了这个家伙,您也可以在 Apache 2.2.x 上使用它。
Download mod_remoteip.c from https://gist.github.com/1042237and compile it with
从https://gist.github.com/1042237下载 mod_remoteip.c并编译
apxs -i -a -c mod_remoteip.c
This should create mod_remoteip.so copy in the modules directory. apxs will also add LoadModule directive in your httpd.conf for newly created module.
这应该在模块目录中创建 mod_remoteip.so 副本。apxs 还将在您的 httpd.conf 中为新创建的模块添加 LoadModule 指令。
Open httpd.conf and check does LoadModule directive for mod_remoteip exists
打开 httpd.conf 并检查 mod_remoteip 的 LoadModule 指令是否存在
LoadModule remoteip_module modules/mod_remoteip.so
Add RemoteIPHeader directive in httpd.conf
在 httpd.conf 中添加 RemoteIPHeader 指令
RemoteIPHeader X-Forwarded-For
This directive will instruct mod_remoteip to use X-Forwarded-For value from nginx as remote_addr. You can also use X-Real-IP instead:
该指令将指示 mod_remoteip 使用来自 nginx 的 X-Forwarded-For 值作为 remote_addr。您也可以使用 X-Real-IP 代替:
RemoteIPHeader X-Real-IP
Restart the Apache. If you have set the proxy headers in nginx it will work like a charm and remote_addr in Apache will be correct
重新启动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;
回答by Trevorw
Apache (requires mod_headers module):
Apache(需要 mod_headers 模块):
SetEnvIf X-Real-IP "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFF_CLIENT_IP=
RequestHeader set REMOTE_ADDR %{XFF_CLIENT_IP}e
REF for SetEnvIf RegEx: https://stackoverflow.com/a/10346093
SetEnvIf 正则表达式的参考:https://stackoverflow.com/a/10346093
Works also but doesn't verify input as IP:
也可以工作,但不会将输入验证为 IP:
SetEnvIf X-Real-IP "^(.*)" XFF_CLIENT_IP=
RequestHeader set REMOTE_ADDR %{XFF_CLIENT_IP}e
In PHP:
在 PHP 中:
$_SERVER["HTTP_REMOTE_ADDR"]
-or-
-或者-
$_SERVER["REMOTE_ADDR"]
No non-core Apache modules required
不需要非核心 Apache 模块
回答by Yasuo Ohgaki
You may try this simple PHP module
你可以试试这个简单的 PHP 模块
https://github.com/yohgaki/realip
https://github.com/yohgaki/realip
It simply rewrites $_SERVER['REMOTE_ADDR'] with X-Forwarded-For or X-Real-IP whatever header you like. You can accomplish this with many different method, but I just would like to do it as PHP module. So I wrote it.
它只是简单地用 X-Forwarded-For 或 X-Real-IP 重写 $_SERVER['REMOTE_ADDR'] 任何你喜欢的头。您可以使用许多不同的方法来完成此操作,但我只想将其作为 PHP 模块来完成。所以我写了。
回答by wacto
mod_rpaf (sudo apt-get install libapache2-mod-rpaf)
mod_rpaf (sudo apt-get install libapache2-mod-rpaf)
resolved all issues and REMOTE_ADDRR now looks Ok!..
解决了所有问题,REMOTE_ADDRR 现在看起来不错!..
回答by Pekka
I don't know whether REMOTE_ADDR can be manipulated - it could be that it can't - but you should be able to get hold of the X-Real-IP header within PHP through something like
我不知道 REMOTE_ADDR 是否可以被操纵 - 它可能不能 - 但你应该能够通过类似的东西在 PHP 中获取 X-Real-IP 标头
$_SERVER["HTTP_X_Real_IP"]
$_SERVER["HTTP_X_Real_IP"]
or similar - check phpinfo()for the correct notation.
或类似 - 检查phpinfo()正确的符号。
Also, Apache environment variables set in .htaccessshould be visible in PHP.
此外,.htaccess在 PHP 中设置的 Apache 环境变量应该是可见的。
回答by dmp
Off the cuff.. but could you pass the header X-Real-IP as a variable to the php using some rewrite magic..? Can't htaccess do stuff with header information before it invokes PHP?
袖手旁观..但是你能不能使用一些重写魔术将标题X-Real-IP作为变量传递给php..?htaccess 不能在调用 PHP 之前处理头信息吗?
回答by n_are_q
You probably want to use this actually: http://httpd.apache.org/docs/2.3/mod/mod_remoteip.html. Has quite a bit more features and is maintained by apache themselves.
您可能想要实际使用它:http: //httpd.apache.org/docs/2.3/mod/mod_remoteip.html。有相当多的功能,并由 apache 自己维护。
Edit: I was referring to the mod_rpaf suggestion above.
编辑:我指的是上面的 mod_rpaf 建议。

