是什么决定何时 mod_proxy 有时仅将内部 ip 地址添加到 X-Forwarded-For header

What determines when mod_proxy only sometimes add internal ip addresses to X-Forwarded-For header

我一直在尝试使用 Apache mod_proxy 和 mod_remoteip 来确认我对 X-Forwarded-For header 的处理的理解,特别是关于如何处理内部 IP正在处理地址(例如 10.x.x.x 或 192.168.x.x 范围)。

似乎 mod_proxy 并不总是将内部 IP 地址添加到 X-Forwarded-For header,但我一直无法找到任何解释预期行为的文档这个。

据我所知,当请求从内部 IP 地址发起时,mod_proxy 会将内部 IP 地址添加到 X-Forwarded-For header,但是当初始请求来自 public IP,mod_proxy 似乎没有向 X-Forwarded-For.

添加任何内部 IP 地址

问题

我的问题是:决定 mod_proxy 是否将呼叫 IP 地址附加到 X-Forwarded-For header.

的规则是什么?

documentation on mod_proxy 说:

When acting in a reverse-proxy mode (using the ProxyPass directive, for example), mod_proxy_http adds several request headers in order to pass information to the origin server. These headers are:

X-Forwarded-For - The IP address of the client.

X-Forwarded-Host - The original host requested by the client in the Host HTTP request header.

X-Forwarded-Server - The hostname of the proxy server.

Be careful when using these headers on the origin server, since they will contain more than one (comma-separated) value if the original request already contained one of these headers. For example, you can use %{X-Forwarded-For}i in the log format string of the origin server to log the original clients IP address, but you may get more than one address if the request passes through several proxies.

我读到的意思是客户端 IP 地址将始终附加到 X-Forwarded-For header,但这不是我观察到的行为。

这个问题的其余部分是我进行的测试和我观察到的行为。

设置

我已经设置了两台服务器,它们都是 运行 Apache 并安装了 mod_proxy。我将它们称为一和二。

One 具有以下 ProxyPass 指令,因此对 /proxyToTwo 的 sub-paths 的请求将发送到 Two

上 /proxyToOne 下的等效 sub-path
<Location "/proxyToTwo">
        ProxyPass http://10.0.7.2/proxyToOne
</Location>

Two 具有以下 ProxyPass 指令,因此对 /proxyToOne 的 sub-paths 的请求将发送回 One,但没有 /proxyToOne 前缀

<Location "/proxyToOne">
        ProxyPass http://10.0.7.1
</Location>

这样做的效果是,当我向 http://One/proxyToTwo/foo 发出请求时,它被代理如下

  1. 一收到请求,向二发出以下请求http://10.0.7.2/proxyToOne/foo
  2. 二号收到请求,向一号发回以下请求http://10.0.7.1/foo
  3. 一个收到 /foo 的请求并实际提供资源

因此,每个请求都会从一退回到二,然后再返回一,然后再响应二。

使用内部 IP 调用

使用上面的设置,我使用它的内部 IP 地址从二中调用一:

curl http://10.0.7.1/proxyToTwo/foo

X-Forwarded-For 和 X-Forwarded-Host header 当一个人最终得到对 /foo 资源的请求时收到的是我在下面所期望的:

X-Forwarded-For: 10.0.7.2, 10.0.7.1
X-Forwarded-Host: 10.0.7.1, 10.0.7.2

这是我所期望的,请求首先通过一个代理,然后是二个,请求的 IP 地址首先是来自二 (curl) 的初始请求,然后是来自一 (mod_proxy) 的请求,然后最终请求(不在 header 中,因为它是来自两个 (mod_proxy)

的连接的客户端 IP

外网IP调用

意外的行为是 mod_proxy 从 public IP 调用时似乎表现不同。因此,我没有从二中调用一,而是使用 public 地址

从我的本地计算机调用一
curl http://35.162.28.102/proxyToTwo/foo

X-Forwarded-Host还是我期待的:

X-Forwarded-Host: 35.162.28.102, 10.0.7.2

也就是说,请求首先通过一个代理(使用它的外部地址)然后通过二代理。

但是 X-Forwarded-For header 只显示我的(外部)IP 地址:

X-Forwarded-For: 35.163.25.76

这向我暗示 mod_proxy 的初始执行是将 X-Forwarded-For header 添加到客户端 IP 地址。但是随后二的代理不会附加一的地址。

我认为这种行为可能比盲目地将内部 IP 地址附加到 header 更有用,但我无法在任何地方找到它的文档,所以想确保我完全理解它。

回答此问题以便它可用in-case其他人也犯了类似的错误。

简而言之:mod_proxy 始终将客户端 IP 附加到 X-Forwarded-For header(或者如果没有 X-Forwarded-For header header).

但是,其他 Apache 模块可以在 mod_proxy 处理它之前操纵 X-Forwarded-For header。 Mod_proxy 会将客户端 IP 附加到它所看到的 X-Forwarded-For header,它可以是其他 Apache 模块的输出。

在我的测试中,影响结果的另一个模块是 mod_remoteip. The reason for the difference in resulting behavior was that I was using the RemoteIpTrustedProxy 指定我信任的代理的指令,这将允许信任私有 IP 作为第一个连接,但不会处理 [=60 中的私有 IP =] header.

作为外部 IP 案例的结果,有以下处理:

  1. 我的机器 (35.163.25.76) 连接到一个没有 X-Forwarded-For
  2. 一个用我在 X-Forwarded-For header (X-Forwarded-For: 35.163.25.76)
  3. 中的 IP 将此请求发送给两个
  4. Two 收到此请求,mod_remoteip 处理 X-Forwarded-For header,因为 One 是可信的,客户端 IP 实际上是 35.163.25.76 并且实际上没有 X-Forward-For header 传递给 mod_proxy
  5. 两个用我的 IP 在 X-Forwarded-For header (X-Forwarded-For: 35.163.25.76)
  6. 中将此请求发送给一个

这就是显示为 "not appending the private IP" 但实际上正在处理 X-Forward-For header 并生成相同的结果。

私有 ID 案例的行为不同,因为 mod_remoteip 不接受 X-Forward 中的私有 IP 地址。所以它被处理:

  1. 两个 (10.0.7.2) 连接到一个没有 X-Forwarded-For
  2. 一个用 X-Forwarded-For header (X-Forwarded-For: 10.0.7.2)
  3. 中的 IP 将此请求发送给两个
  4. Two 收到此请求,mod_remoteip 处理 X-Forwarded-For header 但不信任该值,因此保持原样。所以客户端 IP 仍然是一个人的 IP (10.0.7.1) 并且传递给 mod_proxy 的 X-Forward-For header 未被修改
  5. 二将此请求发送给一,将客户端 IP(一)附加到 X-Forwarded-For header,结果是 X-Forwarded-For: 10.0.7.2, 10.0.7.1

我通过从受信任的主机实际发送一些 X-Forwarded-For header 来验证这一点。例如。

curl http://10.0.7.1/proxyToTwo/foo --header "X-Forwarded-For: TrustedHost1, TrustedHost2"

这导致最终 X-Forward-For header 仅包含 TrustedHost1,表明 header 确实由 mod_remoteip 处理,re-issued 由 mod_proxy.