C# 如果 HTTP_X_FORWARDED_FOR 包含多个 IP 地址,我如何从它获取正确的 IP?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/753645/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:51:35  来源:igfitidea点击:

How do I get the correct IP from HTTP_X_FORWARDED_FOR if it contains multiple IP Addresses?

c#

提问by Xaisoft

If Request.ServerVariables["HTTP_X_FORWARDED_FOR"] returns multiple ip's, which one do I take and how would I do it in c#? It is my understanding that if it is blank or null, then the client computer is not going through a proxy and I can just get their ip from Request.ServerVariables["REMOTE_ADDR"]. Is this a correct statement?

如果 Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 返回多个 ip,我应该选择哪一个,我将如何在 c# 中做到这一点?我的理解是,如果它为空或 null,那么客户端计算机不会通过代理,我可以从 Request.ServerVariables["REMOTE_ADDR"] 获取他们的 ip。这是正确的说法吗?

By "which one do I take", I mean do I take the first IP in the list or the last IP and is all I have to do is just split it into an array and take the one I want. I am not really sure how HTTP_X_FORWARDED_FOR works.

通过“我该拿哪个”,我的意思是我是拿列表中的第一个 IP 还是最后一个 IP,我所要做的就是将它拆分成一个数组并取我想要的那个。我不太确定 HTTP_X_FORWARDED_FOR 是如何工作的。

采纳答案by Aziz

According to this, the format of X-Forwarded-For HTTP header is:

根据,格式X -转发,对于HTTP标头是:

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

So the IP address of the client that you want should be the first one in the list

所以你想要的客户端的IP地址应该是列表中的第一个

回答by User

I asked some time ago a very similar question.

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

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

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

As correctly pointed out, you can take the first value considering it to be the client's IP address. But it may as well be company gateway IP.

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

And anonymous proxies will wipe out information in this header anyway, so it is useful but not reliable.

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

回答by Conspicuous Compiler

A further note on the reliability subject:

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

Anyone can forge HTTP_X_FORWARDED_FOR by using a tool such as the Firefox plugin "Tamper Data" or their own local proxy (e.g. Privoxy). This means that the entire string might be fake, and REMOTE_ADDR is the actual original host. It might also mean that the first "client1" address is faked, and then the client connected through a proxy, resulting in proxy1 being the client's IP address and REMOTE_ADDR being the single proxy used.

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

If you are looking to deny access based on IP, I would suggest checking every IP address in the XFF header as well as REMOTE_ADDR.

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

If you're looking to grant access based on the region of an IP, I'd suggest allowing access only if XFF is blank and the IP is from the proper area.

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

As Mastermind already noted, however, there are proxies which will hide the chain of proxies. For instance, the Tor network will make a request appear as if it came from the final proxy machine, rather than the original IP. Anonymizing proxies will often claim they are forwarding for the same IP as reported in REMOTE_ADDR.

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

IP based filtering is generally a pretty crude, last-resort mechanism of access control.

基于 IP 的过滤通常是一种非常粗糙的访问控制的最后手段。

回答by Ben Last

The actual client IP should be the left-most IP address in the header value. You can extract it into an environment variable using a regex:

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

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

Note the use of $1to set the XFFCLIENTIP environment variable to hold the contents of the first group in the regex (in the parentheses).

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

As an example of using this, you can define a log format that uses the variable: this example is one we use internally at nearmap.com, so it logs extra information, but the bit you want is the %{XFFCLIENTIP}eat the beginning. Note the env=XFFCLIENTIPat the end of the line, which means this format is only used if the environment variable is set.

作为使用它的一个例子,你可以定义一个使用变量的日志格式:这个例子是我们在 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