Caddy 服务器,X-Forwarded-For 和欺骗值

Caddy server, X-Forwarded-For and spoofed value

像下面这样使用 Caddy 服务器和 reverse_proxy 服务器:

my.domain.com {
    reverse_proxy * unix//path/to/socket
}

我可以很容易地访问我的请求 headers 在 Python/Flask 中执行以下操作:

request.headers.get('X-Forwarded-For')

其中 returns 值列表,根据请求。 documentation规定第一个值是我依赖的客户端IP,但是我最近发现这个值可以被欺骗,像下面这样:

# Using Python requests
requests.get('https://my.domain.com', headers={'X-Forwarded-For': 'www.google.com'})

在这种情况下,header 值为:

X-Forwarded-For: www.google.com, xxx.xxx.xxx.xxx (在那种情况下,xxx.xxx.xxx.xxx 是我的有效 IP)。

我的问题:如何确定地检索客户端的 IP,排除任何欺骗?

详情:

我在 Flask 中测试了以下 headers,它们都设置为 None 使用我上面的 Caddy 配置:

Remote Addr: 0.0.0.0
X-Forwarded-For: www.google.com, xxx.xxx.xxx.xxx
Remote-Addr: None
Client-Ip: None
X-Forwarded: None
X-Cluster-Client-Ip: None
Forwarded-For: None
Forwarded: None

wikipedia 所述,X-Forwarded-For 的一般格式为:

X-Forwarded-For: client, proxy1, proxy2

其中值是逗号+space 分隔的 IP 地址列表,left-most 是原始客户端,每个传递请求的后续代理添加它收到请求的 IP 地址来自.

在此示例中,请求通过 proxy1、proxy2,然后是 caddy(header 中未显示)。 caddy 显示为请求的远程地址。

由于很容易伪造 X-Forwarded-For 字段,因此应谨慎使用给定的信息。 right-most IP地址始终是连接到最后一个代理的IP地址,这意味着它是最可靠的信息来源。

简而言之:选择最后一个值!