在apache中将REMOTE_ADDR设置为X-Forwarded-For

时间:2010-02-11 20:05:14

标签: apache http cgi

在Apache坐在反向代理(例如Squid)后面的情况下,cgi环境变量REMOTE_ADDR获取代理的地址而不是客户端。

但是,代理将设置一个名为X-Forwarded-For的标头,以包含客户端的原始IP地址,以便Apache可以看到它。

问题是,我们如何让Apache用REMOTE_ADDR标头中的值替换X-Forwarded-For,以便所有Web应用程序都能透明地看到正确的地址?

9 个答案:

答案 0 :(得分:14)

你可以使用mod_rpaf。 http://stderr.net/apache/rpaf/

答案 1 :(得分:6)

请注意,如果请求已遍历多个代理,则X-Forwarded-For标头可能包含列表的IP地址。在这种情况下,您通常需要最左边的IP。您可以使用SetEnvIf:

来提取它
SetEnvIf X-Forwarded-For "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFFCLIENTIP=$1

注意使用 $ 1 设置XFFCLIENTIP环境变量以保存正则表达式中第一个组的内容(在括号中)。

然后,您可以使用环境变量的值来设置标头(或以Apache日志格式使用它,以便日志包含实际的客户端IP)。

答案 2 :(得分:4)

除了前面提到的mod_rpaf之外,似乎mod_extract_forwarded也会执行此功能。

mod_extract_forwarded的一个优点是,EPEL可用于RHEL / CentOS服务器,而mod_rpaf则不可用。

这两个模块似乎都不允许您将代理服务器的整个子网列入白名单,这就是为什么CloudFlare人员创建了自己的插件:mod_cloudflare,应该注意的是,不是像其他两个一样的通用工具;它包含一个硬编码的CloudFlare子网列表。

答案 3 :(得分:3)

是的,我们可以做到这一点。

只需在PHP.ini中添加auto_prepend_file,例如auto_prepend_file = "c:/prepend.php" 并在此文件中添加:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

您需要apache width RemoteIPHeader X-Real-IP中的MOD_REMOTEIP。

干杯,

Guiremach

答案 4 :(得分:2)

不幸的是,

在撰写本文时,freshports.org,people.apache.org或gist.github.com上的后端和分叉都没有工作。它们都基于apache httpd 2.3的早期alpha版本,它既不兼容当前版本的2.2也不兼容2.4。

因此,在尝试调整backport以创建httpd 2.2的实际工作时间浪费时间后,我决定转移到httpd 2.4。在httpd 2.4中,mod_remoteip工作顺利,即使负载均衡器具有永久保持连接,它用于将来自不同实际客户端IP地址的请求代理到后端。我不确定其他模块是否可以处理这种情况(在同一连接中更改每个请求的客户端IP地址)。

答案 5 :(得分:1)

请记住,此值可能会被欺骗。有关跨站点脚本结果的真实示例,请参阅http://blog.c22.cc/2011/04/22/surveymonkey-ip-spoofing/

答案 6 :(得分:1)

目前,建议使用apache模块mod_remoteip; rpaf维护不可靠,可能会引起问题。

答案 7 :(得分:0)

您可以安装模块 mod_extract_forwarded 并将 MEFaccept 参数设置为all。

答案 8 :(得分:0)

Apache 2.4 起,就有mod_remoteip内置模块可以执行此操作。

  1. 启用g++
    (例如mod_remoteip

  2. 创建受信任IP范围(接受远程IP标头的IP)列表。您可以将它们放在a2enmod remoteip

    之类的文件中
  3. 将此行添加到Apache配置:

    conf/trusted-ranges.txt
  4. 更改日志文件格式,以使用RemoteIPTrustedProxyList conf/trusted-ranges.txt 代替%a记录客户端IP。


对于 Cloudflare ,您需要信任其所有IP范围,并且使用自定义标头%h

CF-Connecting-IP

您可以像这样获得Cloudflare范围:

RemoteIPHeader CF-Connecting-IP