Varnish cache purging from dynamically instantiated EC2 instances behind a ELB using HTTP header based authentication

We use a Varnish cache server to do basic page caching for our Rails apps. The application instances are automatically instantiated by a ASG(auto scale group) and all these instances sit behind a ELB. Usually Varnish cache purge requests are only allowed from a few white listed IPs.

Like bellow:

acl purge {  
    "localhost";
    "192.168.55.0"/24;
}

sub vcl_recv {  
    # allow PURGE from localhost and 192.168.55...        
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return(synth(405,"Not allowed."));
        }                
        return (purge);        
    }
}

However, because an ELB doesn’t have a static IP (it changes with time, depending on various factors) and also because our application instances themselves are dynamically instantiated and have no static IPs associated with them, we can’t simply use a white list to allow PURGE requests from our app servers.

Now one solution might be to try and identify a IP range from which our app server IPs are pooled from. However, this isn’t very straight forward. And there is a far easier solution to this problem.

HTTP header based authentication!

sub vcl_recv {  
    ….

    if (req.method == "PURGE") {
        if (req.http.X-Cache-Purge-Auth-Key == "top_secret_password_goes_here") {
           return(purge);
        } else {
           return(synth(403, "Access denied."));
        }
      }

     ….
}

Now of course your ‘password’ is up there in plain text inside your configuration files. But I feel that this is a pretty decent solution to our problem.

Long live simple HTTP auth! :D