首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Heroku上获取客户端的真实IP地址

在Heroku上获取客户端的真实IP地址
EN

Stack Overflow用户
提问于 2013-08-16 09:12:41
回答 2查看 25.3K关注 0票数 41

在Heroku Cedar上,我想获取客户端的IP地址。第一次尝试:

代码语言:javascript
复制
ENV['REMOTE_ADDR']

当然,这是行不通的,因为所有请求都是通过代理传递的。因此,另一种选择是使用:

代码语言:javascript
复制
ENV['HTTP_X_FORWARDED_FOR']

但这不太安全,不是吗?

如果它只包含一个值,我接受这个。如果它包含多个值(逗号分隔),我可以采用第一个值。

但是如果有人操纵了这个值呢?我不能像对ENV['REMOTE_ADDR']那样信任ENV['HTTP_X_FORWARDED_FOR']。而且我也没有可以使用的可信代理的列表。

但是,必须有某种方法来可靠地获取客户端的IP地址。你认识一个吗?

their docs中,Heroku描述了X-Forwarded-For是“连接到Heroku路由器的客户端的原始IP地址”。

这听起来好像Heroku可以用原始的远程IP覆盖X-Forwarded-For。这可以防止欺骗,对吧?有人能证实这一点吗?

EN

回答 2

Stack Overflow用户

发布于 2016-05-06 06:42:03

我在Heroku的支持部门工作,花了一些时间和我们的路由工程师讨论这个问题。我想发布一些额外的信息,以澄清这里发生的一些事情。

上面答案中提供的示例只是巧合地最后显示了客户端IP,这并不是真正有保证的。它不是第一个的原因是因为原始请求声称它转发的是X-Forwarded-For标头中指定的IP。当Heroku路由器收到请求时,它只是将直接连接到X-Forwarded-For列表的IP添加到已注入到请求中的IP之后。我们的路由器始终将连接到我们平台前面的AWS ELB的IP添加为列表中的最后一个IP。这个IP可能是原始的(在只有一个IP的情况下,几乎肯定是),但一旦有多个IP链接在一起,所有的赌注都会失效。约定总是将链中的最新IP添加到列表的末尾(这就是我们所做的),但在链的任何点上,链都可以更改,可以插入不同的IP。因此,唯一可靠的IP (从我们的平台的角度来看)是列表中的最后一个IP。

举个例子,假设有人发起了一个请求,并在X-Forwarded-For报头中随意添加了3个额外的IP:

代码语言:javascript
复制
curl -H "X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4" http://www.google.com

假设这台机器的IP是9.9.9.9,并且它必须通过一个代理(例如,一所大学的校园代理)。假设代理的IP地址为2.2.2.2。假设它没有配置为剥离X-Forwarded-For报头(很可能不会),它只会将9.9.9.9 IP添加到列表的末尾,并将请求传递给谷歌。此时,标头将如下所示:

代码语言:javascript
复制
X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4,9.9.9.9

然后,该请求将通过Google的端点,该端点将附加大学代理的IP 2.2.2.2,因此标头最终将在Google的日志中如下所示:

代码语言:javascript
复制
X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4,9.9.9.9,2.2.2.2

那么,哪个是客户端IP呢?从谷歌的角度来看,这是不可能的。实际上,客户端IP是9.9.9.9。列出的最后一个IP是2.2.2.2,第一个是12.12.12.12。Google所知道的就是2.2.2.2的IP地址是绝对正确的,因为这是实际连接到他们的服务的IP地址--但从可用的数据来看,他们不知道这是否是请求的初始客户端。以同样的方式,当这个头中只有一个IP时-这是直接连接到我们的服务的IP,所以我们知道它是可靠的。

从实际的角度来看,这个IP在大多数情况下可能是可靠的(因为大多数人都不会费心去欺骗他们的IP)。不幸的是,要防止这种欺骗是不可能的,当请求到达Heroku路由器时,我们不可能知道X-Forwarded-For链中的in是否被篡改了。

除了可靠性问题之外,这些IP链应该始终从左到右读取。客户端IP应该始终是最左边的IP。

票数 43
EN

Stack Overflow用户

发布于 2013-08-16 09:45:21

您永远不能真正信任来自客户端的任何信息。这更多的是一个你信任谁以及如何验证的问题。即使是Heroku也可能会受到影响,如果他们的代码中有一个bug,或者他们被黑客攻击了,那么他们可能会提供一个糟糕的HTTP_X_FORWARDED_FOR值。另一种选择是一些其他的Heroku机器在内部连接到你的服务器,并完全绕过他们的代理,同时伪造REMOTE_ADDR和/或HTTP_X_FORWARDED_FOR

这里最好的答案取决于你想要做什么。如果您正在尝试验证客户端,客户端证书可能是更合适的解决方案。如果您只需要地理位置的IP,那么信任输入可能就足够了。最坏的情况是,有人会伪造位置并得到错误的内容...如果您有不同的用例,在这两个极端之间还有许多其他的解决方案。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18264304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档