Search code examples
ccentosvarnishvarnish-4pound

Varnish 4 + Pounds - Bypass cache for specific IP Address


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


Solution

  • 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);
      }
    }