0

I'me trying to configure Varnish to not use cache for specific IPs.

I've configured Varnish 4 on Centos with Apache using Pound to manage HTTPS requests.

I've tried to follow this approach:

Varnish - Bypass Cache for IP Address

based on

https://zcentric.com/2012/03/16/varnish-acl-with-x-forwarded-for-header/

using some C code to manage the IPs. The suggested code is for Varnish3 (e.g. "sp" doesn't exist anymore, now there's a ctx variable)

I've tried to use this approach Inline C Varnish (VCL_deliver) but I get a *"initialization from incompatible pointer type [-Werror] in struct sockaddr_storage client_ip_ss = VRT_r_client_ip(ctx); " error probably because the type has also been changed.

The code I'm trying to use is:

struct sockaddr_storage *client_ip_ss = VRT_r_client_ip(ctx); 
struct sockaddr_in *client_ip_si = (struct sockaddr_in *) client_ip_ss; 
struct in_addr *client_ip_ia = &(client_ip_si->sin_addr); 
const struct gethdr_s hdr = { HDR_REQ, "20X-Forwarded-For:" }; 
char *xff_ip = VRT_GetHdr(ctx, &hdr);

but I'm doing something wrong.

I'm a bit lost now, how can I disable varnish for specific IPs on Varnish 4 ?

Thanks

SimoneB
  • 592
  • 1
  • 6
  • 16

1 Answers1

1

Please don't write inline C in Varnish: it's risky and the solution you're looking for is already automatically implemented in Varnish.

Keep in mind that Varnish v3 & v4 are no longer supported, please use Varnish 6

Varnish automatically sets the X-Forwarded-For header

If you want to exclude items from the cache based on the X-Forwarded-For value, you can still use client.ip and match the value to an acl.

Varnish will automatically take the IP from its client and store it in the X-Forwarded-For header. This means the value of client.ip is exactly the same as req.http.X-Forwarded-For.

Multiple proxies & the PROXY protocol

When other proxies are used before Varnish is reached, you have to make sure they're communicating over the PROXY protocol. Varnish supports the PROXY protocol, your other proxies should too.

In your case it's Pound. The Varnish community advises Hitch for TLS termination.

Enabling PROXY protocol support in Varnish is done by opening up a specific listening address:

varnishd -a :80 -a :8443,PROXY

Varnish can then accept connections on port 8443 over PROXY protocol.

The main advantage of using the PROXY protocol is that the original client IP address is transmitted all the way to Varnish. Regardless of the number of proxies in front of Varnish, the client.ip value will always be the IP address of the original client.

If Pound doesn't support PROXY protocol, I would advise you to switch to Hitch.

Defining the ACL

Once you manage to setup TLS termination with PROXY protocol support, you can just write some VCL to pass items from the cache as illustrated below:

acl passem { "7x.xxx.xxx.xxx"; }
sub vcl_recv {
  if (!(client.ip ~ passem)) {
    return (pass);
  }
}
Thijs Feryn
  • 3,982
  • 1
  • 5
  • 10
  • Hi, Thanks for your reply. Just a question (could be stupid but I'm not used to varnish): As I want to DISABLE varnish for specific IPS, shouldn't this one if (!(client.ip ~ passem)) { return (pass); } be if ((client.ip ~ passem)) { return (pass); } (no "!" ) – SimoneB Mar 27 '20 at 15:24
  • Sure, depends whether the IPs are in a blacklist or a whitelist. But I guess since the name of the ACL is `passem`, you probably want to pass for those IPs, which makes your comment valid. – Thijs Feryn Mar 28 '20 at 15:17
  • I tried the "varnishd -a" command above but I get "Invalid listen address PROXY (attempting to set param listen_address to :8443,PROXY)" error. Is it supposed to work with Varnish6 only? I MUST use Varnish 4 – SimoneB Apr 01 '20 at 06:48
  • With some debug I noticed that req.http.X-Forwarded-For is in the form [VISITOR IP], 127.0.0.1 so I used this code that seems working: if ((std.ip(regsub(req.http.X-Forwarded-For,", 127.0.0.1",""), "0.0.0.0") ~ passem)) { return(pass); } – SimoneB Apr 01 '20 at 07:26
  • 1
    Here's an old blog post of mine, containing information about Varnish 4.1 (which is currently end-of-life). Please ignore the HAProxy parts: https://feryn.eu/blog/varnish-4-1-haproxy-get-the-real-ip-by-leveraging-proxy-protocol-support/ – Thijs Feryn Apr 01 '20 at 07:53