March 29, 2018
5 min read time

VCL at the edge

samsommer-73414-unsplash

In 'The Odyssey,' Greek poet Homer describes the 'wine-dark sea’. Today we would probably say “dark blue sea”, but at the time Greeks, and other ancient populations, didn’t have a name to describe what we today call “blue”. Blue, though, has always existed.


The same applies to edge computing. Edge logic is not brand new, but it has recently moved center stage, assuming greater importance in ubiquitous conversations and tech media discussions about performance and other edge-related applications, what didn’t necessarily have a name has now been baptized as ‘edge computing’/’edge logic’. Finally, we have a name to use when we talk about something we have always been trying to achieve.

Varnish, as one of my colleagues once said, is the definition of edge logic, and it is quite possibly the pioneer of such a concept, predating a time when the ‘edge’ was on everyone’s lips and minds.

Using VCL (Varnish Configuration Language) you can apply literally any kind of logic to your edge architecture. You are limited only by your imagination and the sophistication of your VCL expertise. Here are a few examples:

 

1. Use VCL to run auth checks at the very edge of your architecture

Using VCL for authentication and authorization, we can in just two steps identify the user and provide the proper content authorization.
With a few lines of VCL you can identify each user:

Example 1:

    sub vcl_recv {
        if (!cookieplus.get("wpadmin") && req.url ~ "^/admin/") {
            return (synth(401));
        }
    }

We use the vmod-cookieplus, which provides advanced functionalities to handle request and response cookie headers, to check if a non-admin user is trying to access an admin page, and if the user has no access rights, we deliver a 401 “Unauthorized” message as response.

Example 2:


    sub vcl_recv {
        unset req.http.authstatus;
        if (req.http.signature) {
            set req.http.sig-verf = digest.hmac_sha256("key", req.http.host);
            if (req.http.sig-verf == req.http.signature) {
                set req.http.authstatus = "ok";
            }
        }
    }

The logic here is the same as in example 1: we check if the user provides a valid “Signature” header when requesting content, and if the user is authorized Varnish delivers the content s/he has access to.
Instead of using vmod-cookieplus, here, we work with a combination of request headers and vmod-digest, which can be used to compute hmac hashes.

Find out more on how authentication and authorization works in Varnish.

 

Once the user is authenticated, still using VCL, we can move on to step number two, the content authorization part, and write VCL logic that defines what content each user is allowed to see.

And this leads us to point number two…

 

2. Use VCL to send a request to another service 

VCL can be used to send a request to a third-party service, such as an authentication server without impacting your performance.


    sub vcl_recv {
        http.init(0);

        http.req_copy_headers(0);
        http.req_set_url(0, "https://example.com/api/authorize");

        // Send the request, we will read the response later
        http.req_send(0);
    }

    sub vcl_deliver {
        // Block for the response
        http.resp_wait(0);

        if (http.resp_get_status(0) == 200) {
            set resp.http.Set-Cookie = http.resp_get_header(0, "Set-Cookie", "session=ERROR");
        } else {
            return(synth(401, "UNAUTHORIZED"));
        }
    }

Using vmod-http, a vmod that opens up to HTTP communication to other services through VCL, we can trigger a request to an authentication service and deliver a response to the end-user including the cookie or any other decision taken by the authentication party.
Combining the previous point with this one you can build your own paywall or any other authentication/authorization scheme.

 

In vcl_recv we set all the parameters and variables necessary to send a HTTP request to a third party, while in vcl_deliver, the subroutine which returns a response to the end user, whether that is to send a Set-Cookie header or let the consumer know s/he is unauthorized.


3. Use VCL to render content in your edge cache to save bandwidth and round trips

vmod-edgestash lets you pre-assemble content within your edge cache.
This saves round trips and bandwidth, which nowadays is still an expensive resource.


    sub vcl_backend_response {
        if (bereq.url ~ "\.json$") {
            edgestash.index_json();
        } else if (bereq.url ~ "/edgestash/.*\.txt$") {
            edgestash.set_delimiter("[", "]");
            edgestash.parse_response();
        }
    }

    sub vcl_deliver {
        if (req.url ~ "/edgestash/.*\.txt$" && edgestash.is_edgestash()) {
            edgestash.add_json_url(regsub(req.url, "\.txt$", ".json"));
            edgestash.execute();
        }

        if (edgestash.is_edgestash() || edgestash.is_json()) {
            set resp.http.X-edgestash = edgestash.version();
        }
    }

In vcl_backend_response we instruct Varnish to index any JSON file fetched from the backend and parse the backend response, while on delivery, Edgestash will execute pre-assembling the response using a Mustache syntax and the values found in the JSON file.
Other than the official VMOD documentation, we also have an Edgestash demo website you can check out.

 

Varnish is all about edge logic and these few lines of VCL illustrate only a small sliver of the immense flexibility this language brings with it: Allowing you to control your content delivery down to the most granular detail as close to your user as you want 1. 

 

1 Setting up your own points of presence and delivering content as close to your most important audience as physically possible is easy with Varnish. You can read more about this and our private CDN offering here.