X-Forwarded-For

X-Forwarded-For(XFF)请求标头是一个事实上的用于标识通过代理服务器连接到 web 服务器的客户端的原始 IP 地址的标头。

警告: 对此标头的不恰当使用可能带来安全风险。有关详细信息,请参阅安全和隐私考虑

当客户端直接连接到服务器时,其 IP 地址被发送给服务器(并且经常被记录在服务器的访问日志中)。但是如果客户端通过正向或反向代理服务器进行连接,服务器就只能看到最后一个代理服务器的 IP 地址,这个 IP 通常没什么用。如果最后一个代理服务器是与服务器安装在同一台主机上的负载均衡服务器,则更是如此。X-Forwarded-For 的出现,就是为了向服务器提供更有用的客户端 IP 地址。

有关使用此标头的详细指引,请参阅解析选择一个 IP 地址部分。

标头类型 请求标头
禁止修改的标头

此标头的标准化版本是 HTTP Forwarded 标头。

安全和隐私考虑

按照设计的目的,此标头暴露隐私敏感信息,比如客户端的 IP 地址。因此,在应用此标头时,需要将用户的隐私问题考虑在内。

当在客户端和服务器之间没有受信任的反向代理服务器时(比如一个负载均衡服务器),X-Forwarded-For 标头是不可信的。如果客户端和所有的代理服务器都没有恶意且行为良好,那么此标头中的 IP 地址列表具有指令部分所描述的意义。但是如果客户端或任意代理服务器存有恶意或配置错误,那么此标头的任意部分(或整体)可能是伪造的(并且有可能不是一个列表或者甚至不包含 IP 地址)。

如果客户端和服务器之间存在任意受信任的反向代理服务器,最终 X-Forwarded-For 中的 IP 地址列表是可信的,因为这些 IP 是由受信任的代理服务器添加的(只要服务器只能通过这些代理服务器进行访问而不是可以被直接访问)。

使用 X-Forwarded-For 进行安全相关的操作时(比如速率限制或基于 IP 的访问控制),必须仅使用由受信任的代理服务器添加的 IP 地址。使用不可信的 IP,可能导致速率限制被规避、访问控制被绕过、内存耗尽,或其他与安全性或可用性相关的负面后果。

反过来,只有当使用伪造的值不会导致负面影响时,最左边的(不可信的)值才能被使用。

语法

http
X-Forwarded-For: <client>, <proxy1>, <proxy2>

元素用逗号分隔,逗号两边可以加上空格。

指令

<client>

客户端的 IP 地址。

<proxy1>, <proxy2>

如果请求经过多个代理服务器,每个代理服务器的 IP 地址会依次出现在列表中。这意味着,如果客户端和代理服务器行为良好,最右边的 IP 地址会是最近的代理服务器的 IP 地址,最左边的 IP 地址会是原始客户端的 IP 地址。

示例

http
X-Forwarded-For: 2001:db8:85a3:8d3:1319:8a2e:370:7348

X-Forwarded-For: 203.0.113.195

X-Forwarded-For: 203.0.113.195, 2001:db8:85a3:8d3:1319:8a2e:370:7348

X-Forwarded-For: 203.0.113.195,2001:db8:85a3:8d3:1319:8a2e:370:7348,150.172.238.178

解析

X-Forwarded-For 标头的不当解析可能导致伪造的值被用于安全相关的目地,造成上文提及过的负面后果。

在一个请求中可能出现多个 X-Forwarded-For 标头。这些标头中的 IP 地址必须被当作一个列表进行处理,从第一个标头中的第一个 IP 地址开始,直到最后一个标头中的最后一个 IP 地址结束。有两种方法生成这个列表:

  • 用逗号拼接所有 X-Forwarded-For 标头的值,然后用逗号将其分割成一个列表
  • 用逗号将每一个 X-Forwarded-For 标头的值都分割成一个列表,然后将这些列表合并成一个列表

只使用多个 X-Forwarded-For 标头中的一个是不够的。

(一些反向代理服务器会自动将多个 X-Forwarded-For 标头合并成一个,但是最安全的做法是不要假设就是这种情况。)

选择一个 IP 地址

选择地址时,必须使用从所有 X-Forwarded-For 标头生成的完整 IP 列表。

当选择离客户端最近的 X-Forwarded-For IP 地址时(不可信并且不用于安全相关的目地),应该选择最左边的、第一个有效且不是私有/内部地址的 IP 地址。(要求”有效“是因为伪造的值可能根本就不是 IP 地址;要求“不是私有/内部地址”是因为客户端使用的代理服务器可能在它们的内部网络中,在这种情况下代理服务器可能添加了私有 IP 地址空间中的地址。)

当选择第一个可信的 X-Forwarded-For 客户端 IP 地址时,需要进行额外的配置。有两种常用的方法:

  • 受信任代理服务器数量:配置了互联网和服务器之间的反向代理服务器数量。从 X-Forwarded-For IP 列表的最右边开始搜索,第(受信任代理服务器数量 - 1)个地址就是目标地址。(例如,如果只有一个反向代理服务器,这个代理服务器会添加客户端的 IP 地址,因此应该使用最右边的地址。如果有三个反向代理服务器,最后两个 IP 地址将是内部地址。)
  • 受信任代理服务器列表:配置了受信任反向代理服务器的 IP 或 IP 范围。从 X-Forwarded-For IP 列表的最右边开始搜索,跳过受信任代理服务器列表中的所有地址。第一个不匹配的地址就是目标地址。

第一个可信的 X-Forwarded-For IP 地址可能属于一个不受信任的中间代理服务器,而不是实际的客户计算机,但这是唯一一个适用于安全用途的 IP 了。

注意如果从互联网可直接连接到服务器——即使服务器也位于一个受信任的反向代理服务器之后——X-Forwarded-For IP 列表中的任何部分都不能被认为是可信赖的,或者可安全地用于安全相关的用途。

规范

不属于任何既有规范。标准版本是 Forwarded

参见