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

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

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

据此,X-Forwarded-For HTTP头的格式为:

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

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

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

获取客户端IP地址:REMOTE_ADDR,HTTP_X_FORWARDED_FOR,还有什么可能有用?

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

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

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

任何人都可以使用诸如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的过滤通常是一种非常粗略的,最后的访问控制机制。

实际的客户端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