覆盖 haproxy 中的 X-Forwarded-For 标头?

覆盖 haproxy 中的 X-Forwarded-For 标头?

在我的 HAProxy 负载均衡器中,我有以下配置块:

defaults
    mode                    http
    log                     global
    option                  httplog clf
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch

frontend  main_http *:80
    option forwardfor except 127.0.0.1
    option httpclose
    default_backend         backend_http

backend backend_http
    balance     roundrobin
    option httpchk
    server  node1 10.0.0.64:80 check port 80
    server  node2 10.0.0.65:80 check port 80
    server  node3 10.0.0.66:80 check port 80

在节点(Tomcat)上,我以这种格式记录请求(结合第一个字段中的 x-forwarded-for 和附加在末尾的实际 REMOTE_ADDR):

pattern='%{X-Forwarded-For}i - %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %a'

对于大多数请求来说,这似乎效果很好,但在某些情况下,我假设客户端本身位于代理后面,我看到请求的第一个字段包含这些值(每行代表一个真实请求,为了保护隐私,我破坏了真实 IP):

10.83.103.44, 10.83.103.44 
10.83.198.52, 10.83.198.52 
10.53.109.36, 10.53.109.36 
unknown, unknown 
192.168.1.43, 127.0.0.1 
192.168.11.189, 127.0.0.1 
10.1.6.3, 216.x.y.194, 10.37.52.202 
192.168.50.250, 38.x.y.5, 10.37.31.201 

根据 HAproxy 文档,最后一个 X-Forwarded-For 应该是它附加的正确 X-Forwarded-For,但事实似乎并非如此。我的应用程序使用客户端 IP 进行地理查找,因此这不仅仅是日志记录问题,它实际上把事情搞砸了。

我想做的是:不要让 HAproxy 将客户端的 IP 附加到它收到的现有 X-Forwarded-For 标头,而是直接覆盖它。因此,如果它X-Forwarded-For: 10.1.2.3从 IP 地址 98.76.54.32 接收,它发送给客户端的只是X-Forwarded-For: 98.76.54.32。有什么办法吗?我想知道为什么如此明显的垃圾信息会进入节点 -unknown, unknown显然是垃圾信息 - 但如果存在解决方法,我会选择一种解决方法。

提前致谢。

答案1

在 HAProxy 添加自己的请求标头之前,将其从请求标头中撕下:

reqidel ^X-Forwarded-For:.*

此更改的风险是您将丢失有关“真实”客户端 IP 地址的信息 - 您的日志将显示客户端正在使用的代理服务器的 IP。听起来您对此没意见!

另外,参见这个问题有关标题附加顺序混淆的一些有趣信息X-Forwarded-For

答案2

如果您仍然感到困惑,可以直接使用以下两个代码片段之一:

第一的:

backend forward_real_ip
    mode http
    reqidel ^X-Forwarded-For:.*
    option forwardfor

第二:

backend forward_real_ip
   mode http
   http-request set-header X-Forwarded-For %[src]

请参阅 HAProxy 文档:

答案3

如果您专门查看 haproxy 文档中的forwardedfor选项,您可以阅读:

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

您可以在配置中更改相应的行,例如:

option forwardfor except 127.0.0.1 header My-X-Forwarded-For

这样,您最终会得到两个X-Forwarded-For标头。这可能对您保持客户端真实 IP 有用,同时,您还可以让 haproxy 插入其标头而不会造成混淆。

这只是您可能感兴趣的另一个选择:)

相关内容