Skip to content

Instantly share code, notes, and snippets.

@inawrath
Created June 14, 2017 20:49
Show Gist options
  • Save inawrath/3341b56a98cd1f349965ff87ac4cd6ab to your computer and use it in GitHub Desktop.
Save inawrath/3341b56a98cd1f349965ff87ac4cd6ab to your computer and use it in GitHub Desktop.
Enabling URL token validation varnish
Enabling URL token validation
Last updated December 15, 2016
Token validation allows you to create URLs that expire. Tokens are generated within your web application and appended to URLs in a query string. Requests are authenticated at Fastly's edge instead of your origin server. When Fastly receives a request for the URL, the token is validated before serving the content. After a configurable period of time, the token expires.
Adding custom VCL
To enable token validation, you'll need to create a Varnish configuration named vcl_recv and add the following example code to it.
IMPORTANT: The ability to upload custom VCL code is disabled by default when you sign up. To enable this ability for your account, contact support@fastly.com and request it.
/* make sure there is a token */
if (req.url !~ ".+\?.*token=(\d{10,11})_([^&]+)") {
error 403;
}
/* extract token expiration and signature */
set req.http.X-Exp = re.group.1;
set req.http.X-Sig = re.group.2;
/* validate signature */
if (req.http.X-Sig == regsub(digest.hmac_sha1(digest.base64_decode("YOUR%SECRET%KEY%IN%BASE64%HERE"),
req.url.path req.http.X-Exp), "^0x", "")) {
/* check that expiration time has not elapsed */
if (time.is_after(now, std.integer2time(std.atoi(req.http.X-Exp)))) {
error 410;
}
} else {
error 403;
}
/* cleanup variables */
unset req.http.X-Sig;
unset req.http.X-Exp;
WARNING: You must replace YOUR%SECRET%KEY%IN%BASE64%HERE in the example VCL with your own randomly generated secret key. The example key will intentionally cause an error if you use it. Anyone who learns this key can bypass your token validation, so it's critical that you keep this key secret.
The key found in digest.hmac_sha1 can be any string. The one in this example was generated with the command openssl rand -base64 32.
A token is expected in the ?token= GET parameter. Tokens take the format [expiration]_[signature] and look like this:
1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
The full request URL looks like this:
http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
What the custom VCL does
The custom VCL code checks for two things:
Is the current time greater than the expiration time specified in the token?
Does our signature match the signature of the token?
If the signature is invalid, Varnish returns a 403 response. If the signature is valid but the expiration time has elapsed, Varnish returns a 410 response. The different response codes are helpful for debugging.
Configuring your application
You'll need to write custom code in your application to generate tokens and authenticate with Varnish. We provide examples in our token functions repository on GitHub. Review the examples in the repository to learn how to generate custom tokens within your application.
Testing
To test your configuration, append a token generated by your application to a URL in a query string. For example:
http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
If the token is valid, you will receive a normal response. If it is invalid, you will receive a 403 response.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment