Using basic authentication in VCL backend probes

Tags: vcl (20) probe (1) backend (2) authorization (1)

When your Varnish server proxies requests to a backend that requires authorized access via basic authentication, you need to ensure that the right Authorization header is sent for each probe request.

1. Initial situation

Your initial backend setup will have a backend that may contain a .probe {} definition.

This health-checking probe will send HTTP requests to your backend server at regular intervals. As long as a 200 status code is returned, the backend is considered healthy.

Here’s the VCL code that contains a basic .probe {} definition for the backend:

vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .probe = {
        .url = "/";
        .timeout = 2s;
        .interval = 5s;
        .window = 10;
        .threshold = 5;
   }
}

2. Unauthorized access

Because our initial health probe definition doesn’t contain the right Authorization header, the health probe will receive the following error:

HTTP/1.1 401 Unauthorized

The probe sees this as a failed response and will eventually result in the backend becoming sick. This is also reflected in the Varnish Shared Memory Log output:

varnishlog -g raw -i backend_health
  0 Backend_health - boot.default Still sick 4---X-R- 4 5 10 0.000534 0.000000 HTTP/1.1 401 Unauthorized

Sick backends are not used and if no healthy backend is found, Varnish will return the following error when it attempts to fetch content from the backend:

HTTP/1.1 503 Backend fetch failed

3. Sending the right HTTP request

The goal is to add an Authorization header to the HTTP request that the health probe uses. This would be the preferred HTTP request:

HEAD / HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Host: localhost
Connection: close
User-Agent: Varnish Health Probe

4. VCL example with basic authentication

Instead of using the .url property in our health-checking probe, we can use the .request property to send a custom HTTP request.

The following VCL code contains an updated probe definition that supports basic authentication:

vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .probe = {
        .request =
            "HEAD / HTTP/1.1"
            "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="
            "Host: localhost"
            "Connection: close"
            "User-Agent: Varnish Health Probe";
        .timeout = 2s;
        .interval = 5s;
        .window = 10;
        .threshold = 5;
   }
}

5. The end result

As you can see in the VCL example, the Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= is part of the probe’s HTTP requests. As long as the login credentials are correct, the health checks will succeed, and the backend will be considered healthy.

This is also reflected in the Varnish Shared Memory Log output:

varnishlog -g raw -i backend_health
  0 Backend_health - boot.default Still healthy 4---X-RH 7 5 10 0.000871 0.000551 HTTP/1.1 200 OK