在我的HAProxy负载平衡器中,我有以下configuration块:
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)上,我以这种格式logging请求(与第一个字段中的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.xy194, 10.37.52.202 192.168.50.250, 38.xy5, 10.37.31.201
根据HAproxy文档,最后的X-Forwarded-For应该是它附加的正确的那个,但这似乎并不是这样。 我的应用程序使用客户端IP进行地理查找,所以这不仅仅是一个日志logging问题,实际上是搞砸了。
我想要做的是:不要让HAproxy将客户端的IP附加到它接收到的现有的X-Forwarded-For头上,而是简单地覆盖它。 因此,如果从IP地址98.76.54.32收到X-Forwarded-For: 10.1.2.3 ,它将发送给客户端的只是X-Forwarded-For: 98.76.54.32 。 有没有办法做到这一点? 我想知道为什么这样明显的垃圾正在把它交给节点 – unknown, unknown的显然是垃圾信息 – 但如果存在的话,我会解决一个解决方法。
提前致谢。
在HAProxy添加自己的请求之前把它从请求标题中撕下来:
reqidel ^X-Forwarded-For:.*
这种变化的风险在于,您将失去有关“真实”客户端IP地址的信息 – 您的日志将显示客户端正在使用的代理服务器的IP。 听起来你可以这样做!
顺便说一下,看到这个问题的一些有趣的信息在X-Forwarded-For头的追加顺序上的混淆。
如果您在forwardedfor选项中专门查看haproxy文档,则可以阅读:
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
你可以在configuration中改变相应的行,如:
option forwardfor except 127.0.0.1 header My-X-Forwarded-For
这样,您最终将拥有两个X-Forwarded-For标头。 保持客户真正的IP地址对你来说可能是有用的,同时,你可以让haproxy插入头部而不会混淆。
这只是您可能感兴趣的另一个选项:)