nginx behind haproxy behind varnish

By | December 14, 2017
Questions:

my nginx server is behind haproxy, which is behind Varnish :

Request web => Varnish => HaProxy => Nginx

The problem I have is I cannot retrieve the ip adress of the client, in the nginx logs I have just the ip address of the haproxy, so I think my XForwardfor is bad.

This is what I put for Varnish:

remove req.http.X-Forwarded-For;
set    req.http.X-Forwarded-For = req.http.rlnclientipaddr;

This is what I put on haproxy:

option forwardfor

And in nginx I’ve configure the http_real_ip_module and I have:

set_real_ip_from 192.168.1.2;
real_ip_header X-Forwarded-For;

Thanks

PS: If I remove Varnish, and I put Haproxy on the port 80, I have the real ip adresses.

Answers:

Haproxy does not appear to really consume the x-forwarded-for header. It appears that it simply replaces it. If you are running on a later version of 1.5 (I think 17 or greater) then you can actually do variable concatenation which means that you can set the x-forwarded-for header yourself without using option forwardfor. I am doing this in a very large haproxy implementation and it is working very well.

Another option is to change the haproxy option forwardfor header to use a different header. This means that on the nginx server you would have to look at two headers. The one from varnish would have the end user IP address, the one from haproxy would have the varnish servers IP address. To do this, the haproxy config looks like this:

option forwardfor header varnish-x-forwarded-for

Questions:
Answers:

Make sure Varnish is setting the proper header.

The actual code for setting X-Forwarded-For in Varnish should be, as stated on default.vcl [1]:

sub vcl_recv {
  if (req.restarts == 0) {
    if (req.http.x-forwarded-for) {
      set req.http.X-Forwarded-For =
          req.http.X-Forwarded-For + ", " + client.ip;
    } else {
      set req.http.X-Forwarded-For = client.ip;
    }
  }
  # ...
}

[1] https://www.varnish-cache.org/docs/3.0/reference/vcl.html#examples

Leave a Reply

Your email address will not be published. Required fields are marked *