64

我发现了一些关于X-Forwarded-*标题的有趣读物,包括 Apache 文档中的 Reverse Proxy Request Headers部分,以及关于 X-Forwarded-For 的 Wikipedia 文章

我明白那个:

  • X-Forwarded-For给出连接到代理的客户端地址
  • X-Forwarded-Port提供客户端连接到代理上的端口(例如80443
  • X-Forwarded-Proto给出客户端用于连接代理的协议(httphttps
  • X-Forwarded-Host给出Host客户端发送到代理的标头内容。

这些都是有道理的。

但是,我仍然无法弄清楚X-Forwarded-Host. 我知道需要在不同的端口上重复连接或使用不同的方案,但是为什么代理服务器Host在向目标服务器重复请求时会更改标头?

4

7 回答 7

26

如果您使用Apigee之类的前端服务作为 API 的前端,您将需要 X-FORWARDED-HOST 之类的东西来了解用于连接 API 的主机名,因为 Apigee 会使用您的后端 DNS 进行配置也就是说,nginx 和您的应用程序堆栈仅将 Host 标头视为您的后端 DNS 名称,而不是最初调用的主机名。

于 2014-01-28T19:06:38.930 回答
19

这是我今天工作的场景:用户使用指向反向代理的“ https://neaturl.company.com ”URL访问某些应用程序服务器。然后代理终止 SSL 并将用户的请求重定向到 URL 为“ http://192.168.1.1:5555 ”的实际应用程序服务器。问题是 - 当应用程序服务器需要使用绝对路径将用户重定向到同一服务器上的其他页面时,它使用的是后一个 URL,用户无权访问它。使用 X-Forwarded-Host(+ X-Forwarded-Proto 和 X-Forwarded-Port)允许我们的代理告诉应用程序服务器用户最初使用哪个 URL,因此服务器开始在其响应中生成正确的绝对路径。

在这种情况下,没有选项可以停止应用程序服务器生成绝对 URL,也无法手动将其配置为“公共 url”。

于 2015-05-14T22:13:41.120 回答
11

我可以告诉你一个现实生活中的问题,我在使用 IBM 门户时遇到了问题。

在我的情况下,问题是 IBM 门户有一个休息服务,它检索资源的 url,例如:{“url”:“ http://internal.host.name/path ”}

发生了什么?很简单,当您从 Intranet 输入时,一切正常,因为 internalHostName 存在但是......当用户从 Internet 输入时,代理无法解析主机名并且门户崩溃。

IBM 门户的修复是读取 X-FORWARDED-HOST 标头,然后将响应更改为:{“url”:“ http://internet.host.name/path ”}

看到我在第二个响应中放入了互联网而不是内部。

于 2014-03-03T12:58:47.437 回答
5

对于“x-forwarded-host”的需要,我可以想到一个虚拟主机场景,其中有几个内部主机(内部网络)和一个位于这些主机和互联网之间的反向代理。如果请求的主机是内部网络的一部分,则请求的主机解析为反向代理 IP,并且 Web 浏览器将请求发送到反向代理。该反向代理找到合适的内部主机,并将客户端发送的请求转发到该主机。这样做时,反向代理会更改主机字段以匹配内部主机,并将 x-forward-host 设置为客户端请求的实际主机。有关反向代理的更多详细信息,请参见此维基百科页面http://en.wikipedia.org/wiki/Reverse_proxy

查看这篇文章以获取有关 x-forwarded-for 标头的详细信息和一个简单的演示 python 脚本,该脚本显示了 Web 服务器如何检测代理服务器的使用:x-forwarded-for 解释

于 2013-12-10T03:43:25.050 回答
3

一个示例可能是阻止某些主机并将它们重定向到外部阻止页面的代理。事实上,我几乎可以肯定我的学校过滤器会这样做……</p>

(他们可能不会像原来Host那样传递原始数据的Host原因是因为某些服务器 [Nginx?] 拒绝任何错误的流量Host。)

于 2013-09-29T23:11:59.107 回答
3

X-Forwarded-Host 刚刚救了我的命。CDN(如果您想深入“树”,则为反向代理)确定用户使用 Host 标头使用哪个来源。因此,CDN 不能使用相同的 Host 标头来联系源 - 否则,CDN 将在循环中转到自身而不是转到源。因此,CDN 使用 IP 地址或一些虚拟 FQDN 作为从源获取内容的主机标头。现在,来源可能希望知道请求内容的 Host 标头(又名网站名称)是什么。就我而言,一个来源服务于 2 个网站。

于 2015-09-29T00:17:46.843 回答
0

另一种情况是,您将应用程序许可到主机 URL,然后您希望在 n > 1 个服务器之间进行负载平衡。

于 2015-11-13T09:17:26.743 回答