So I have a setup like Nginx -> varnish -> apache2
If I get a request with a static file it is sent through nginx to varnish and back to nginx again since its a lot faster than letting apache2 server it. My problem is that when I do a
sub vcl_fetch {
set beresp.http.X-Tabulex-Client = client.ip;
to see what the clients ip address is I am being told its 127.0.0.1 (X-Tabulex-Client 127.0.0.1) In the vcl_recv I have:
sub vcl_recv {
if ((!req.url ~"^/typo3temp/*" && !req.url ~"^/typo3/*") &&req.url ~"\.(jpg|css|gif|png|js)(\?.*|)$"){
set req.backend = aurum;
set client.identity = req.http.X - Forwarded - For;
} elseif(client.ip == "192.168.3.189") {
/* Traffic from the other Varnish server, serve using real backends */
set req.backend = balance;
/* Set client.identity to the X-Forwarded-For (the real IP) */
set client.identity = req.http.X - Forwarded - For;
} else{
/* Traffic coming from internet, use the other Varnish as backend */
set req.backend = iridium;
}
}
The nginx config contains
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_intercept_errors on;
when sending to varnish the first time and nothing when receiving from varnish again.
Im not sure where the problem is. I would expect the client.ip to contain the external ip address so I could use it for acl. Any ideas?
Best Answer
The value of
client.ip
is127.0.0.1
becausenginx
is the client. It wouldn't make sense for Varnish to mask this value -- even in situations like yours where Varnish is sitting behind a front-end proxy, you often want to base decisions on the ip address of the thing actually making the connecting to Varnish.What you really want to do is have
nginx
put the remote client ip address into a dedicated header (which you're already doing withX-Real-IP
) and use that for making connection decisions. We do exactly this in our environment where we have Apache provided SSL connectivity in front ofvarnish
, and then we use this header to make access decisions.It's not as nice as using
client.ip
(you can't match it usingacl
s), but it works. We do something like this:Varnish doesn't provide a native mechanism for overriding
client.ip
with a custom header, but it is possible to solve the problem anyway because you can insert arbitrary C code into your configuration.Here is an example that exactly parallels your situation that includes an example of replacing
client.ip
with another value so that it can be used in Varnish ACLs.