Haproxy option forwardfor works only on first request

haproxy

Why does haproxy send the X-Forwarded-For header only the first time ?

This is the (only) place I have set option forwardfor:

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    server  host     ip:80  check

Only the first HTTP request contains the X-Forwarded-For header:

Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic Og==
Connection: keep-alive
Cache-Control: max-age=0
X-Forwarded-For: replaced_actual_ip

The same header is missing on consecutive requests:

Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic Og==
Connection: keep-alive
Cache-Control: max-age=0

Does anybody have an idea why this might happen ?

(I used this:

tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -n -A

on the backend http server end to dump the headers)

Best Answer

First, in order to use Keep Alive in this way, you need to use HAProxy 1.5. In 1.4, that is the expected behavior. If it does not suit you, you will need to close connections.

In 1.5 the default proxy mode for Keep Alive will have the expected behavior. If you look in the manual of HAProxy 1.5, at section 1.1 "The Transaction Model", you will see 5 connection modes. One of them is "tunneled" which is the behavior that HAProxy had until version 1.5 for Keep Alive connections and will help you understand why it behaves like this.

Related Topic