Excluding IPs from HTTP auth when Apache is behind Varnish

I had a situation whereby I had to protect a site with HTTP auth, but exclude a certain IP address or two from having to use HTTP auth (e.g loadtesting).

The problem was, the site was also behind a Varnish proxy. So I couldn't do 'Allow from (ip)' in the Apache settings, because the IP would always be the IP address of the Varnish server at this point.

And obviously, I couldn't 'Allow from (varnish ip)' because that's the same as not having any HTTP auth at all :)

In the end, I realised I could unset req.http.Authorization in the Varnish VCL, and set a special custom header at the same time, if the IP matched. This went in vcl_recv():

  if (client.ip == "1.2.3.4" || client.ip == "5.6.7.8") {
    unset req.http.Authorization;
    set req.http.SkipAuth = "some random string";
  }

Then in the Apache config:

<location>
    AuthType Basic
    AuthName "Restricted Site"
    AuthBasicProvider file
    AuthUserFile /path/to/htpasswd
    Require valid-user
    Order allow,deny
    SetEnvIf ^SkipAuth* "some random string" allow
    Allow from env=allow
</location>

In retrospect, the unset req.http.Authorization is probably not even necessary here, but I left it in anyway so it's clear to me what Varnish was trying to do here. Additionally, by unsetting it, you can then do things like allow Varnish to cache the request for those end users, if you already had the usual clause that forces Varnish to 'miss' if req.http.Authorization is present. (again, useful for when wanting to do loadtesting and ensure the caching is working)

Tags: