如果HTTP_X_FORWARDED_FOR包含多个IP地址,如何从IP中获取正确的IP?

时间:2009-04-15 20:46:59

标签: c#

如果Request.ServerVariables [“HTTP_X_FORWARDED_FOR”]返回多个ip,我会采取哪一个,如何在c#中执行?我的理解是,如果它是空的或null,那么客户端计算机不通过代理,我可以从Request.ServerVariables [“REMOTE_ADDR”]获取它们的ip。这是正确的陈述吗?

通过“我应该选择哪一个”,我的意思是我在列表或最后一个IP中获取第一个IP,而我所要做的就是将其拆分为一个数组并取出我想要的数据。我不确定HTTP_X_FORWARDED_FOR是如何工作的。

4 个答案:

答案 0 :(得分:37)

根据this,X-Forwarded-For HTTP标头的格式为:

X-Forwarded-For: client1, proxy1, proxy2, ...

因此,您想要的客户端的IP地址应该是列表中的第一个

答案 1 :(得分:3)

前段时间我问了一个非常相似的问题。

Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?

正确指出,您可以将第一个值视为客户端的IP地址。但它也可能是公司网关IP。

无论如何,匿名代理会消除此标题中的信息,因此它很有用但不可靠。

答案 2 :(得分:2)

关于可靠性主题的进一步说明:

任何人都可以使用诸如Firefox插件“Tamper Data”之类的工具或他们自己的本地代理(例如Privoxy)来伪造HTTP_X_FORWARDED_FOR。这意味着整个字符串可能是假的,REMOTE_ADDR是实际的原始主机。这也可能意味着第一个“client1”地址是伪造的,然后客户端通过代理连接,导致proxy1是客户端的IP地址,REMOTE_ADDR是使用的单个代理。

如果您希望拒绝基于IP的访问,我建议您检查XFF标头中的每个IP地址以及REMOTE_ADDR。

如果您希望根据IP区域授予访问权限,我建议仅在XFF为空且IP来自适当区域时才允许访问。

然而,正如Mastermind已经指出的那样,有些代理会隐藏代理链。例如,Tor网络将使请求看起来好像来自最终代理机器,而不是原始IP。匿名代理通常会声称他们转发的内容与REMOTE_ADDR中报告的IP相同。

基于IP的过滤通常是一种非常原始的,最后的访问控制机制。

答案 3 :(得分:0)

实际的客户端IP应该是标头值中最左侧的IP地址。您可以使用正则表达式将其提取到环境变量中:

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

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

作为使用它的一个示例,您可以定义使用该变量的日志格式:此示例是我们在nearmap.com内部使用的示例,因此它记录了额外的信息,但您想要的位是% {XFFCLIENTIP} e 一开始。请注意该行末尾的 env = XFFCLIENTIP ,这意味着仅在设置了环境变量时才使用此格式。

CustomLog /var/log/apache2/access.log "%{XFFCLIENTIP}e \"%{session}C\" \"%{nearmapuid}C\" %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" env=XFFCLIENTIP