Overriding the X-Forwarded-For header in haproxy?
In my HAProxy load balancer, I have the following config chunks:
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
On the nodes (Tomcat), I'm logging requests in this format (combined with x-forwarded-for in the first field and the real REMOTE_ADDR tacked onto the end):
pattern='%{X-Forwarded-For}i - %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %a'
This seems to work well for most requests, but in some cases, I assume in which the clients are behind proxies themselves, I'm seeing requests where the first field contains these values (each line represents one real request, I mangled the real IPs for privacy):
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
According to the HAproxy docs, the last X-Forwarded-For should be the correct one that it appended, but this doesn't appear to be the case. My application uses the client IP for a geo lookup, so this isn't just a logging issue, it's actually screwing things up.
What I'd like to do is: instead of having HAproxy append the client's IP to the existing X-Forwarded-For header it receives, simply overwrite it. So if it receives X-Forwarded-For: 10.1.2.3
from IP addres 98.76.54.32, what it would send to the clients is just X-Forwarded-For: 98.76.54.32
. Is there any way to do this? I'd like to know why such obvious junk is making it to the nodes - unknown, unknown
is clearly junk info - but I'll settle for a workaround if one exists.
Thanks in advance.
Solution 1:
Tear it off the request header, before HAProxy adds its own:
reqidel ^X-Forwarded-For:.*
The risk to this change is that you'll lose your information about the "real" client IP address - your logs will then be showing the IP of the proxy server that the client is using. Sounds like you're ok with that!
As an aside, see this question for some interesting info on confusion over the append order of the X-Forwarded-For
header.
Solution 2:
For anyone who is still puzzled, you can use one of these two snippets directly:
First:
backend forward_real_ip
mode http
reqidel ^X-Forwarded-For:.*
option forwardfor
Second:
backend forward_real_ip
mode http
http-request set-header X-Forwarded-For %[src]
See the HAProxy docs:
- Rewriting HTTP Protocol
- reqidel