In the following setup:
Client -> LB -> Varnish
I would like to configure Varnish acls to take certain action based on the Client's IP. The LB sends the client's IP in a variable called "ClientIP", which Varnish can read via req.httpd.ClientIP.
I tried this:
acl admin_net {
"10.10.1.160"/27;
}
sub vcl_deliever {
if (req.http.ClientIP ~ admin_net) {
// do something ...
}
}
but the VCL compilation fails with "Expected CSTR got 'admin_net'" (C String?). I can work around this by req.http.ClientIP ~ "10.10.1.*")
, but I have to comment out the ACL lines.
Is there another way to get this working with ACLs? I looked at client.ip
as well, which is a read-only variable. In the above setup, it contains the LB's IP and not the Client's IP.
This can be done using std.ip, assuming ClientIP header is already set in vcl_recv(). For example:
Actually Varnish handles client.ip as a different data type and so you can use ACLs against this value. This doesn't work with text values like req.http.ClientIP (or all req.http.* parameters). So a regex with this text value seems to be a good solution.
Alternatively you can use a specific module to set client.ip. I found this for example: http://lassekarstensen.wordpress.com/2013/07/22/setting-client-ip-in-varnish-vcl-with-libvmod-ipcast/
The answer from alexus is actually the right answer if your Loadbalancer supports the "PROXY"-protocol as outlined here: https://info.varnish-software.com/blog/topic/proxy-protocol
With the PROXY protocol your Loadbalancer will inform Varnish of the real client ip address and set client.ip accordingly.
Alexus' code works:
The above code example will do exactly what you want. Loadbalancers which support the PROXY protocol include:
.. just to name a few. Here is a more complete list: https://www.haproxy.com/blog/haproxy/proxy-protocol/
following is how I implement acl in my varnish:
try looking inside of
varnishlog
and post output, it'll be easier to figure out what's wrong...