Varnish is an excellent caching application, it’s what it’s designed for after all. However the fact that it ships with a built-in programming language (VCL) makes it very useful for tweaking how your site responds to HTTP requests. Often these can be things that you don’t really want your website to be concerned with, like sending some standard HTTP headers. Also it’s great for stopping unwanted requests from getting to your webserver, e.g. enforcing HTTPS.
Customising response headers
There are a number of HTTP response headers that your site should send to assist with securing your site. A great place to start is to go to https://securityheaders.io and scan your site and see what recommendations it has. Here are a few that it would be good to set:
X-Frame-Options- Don’t let your site be put inside a frame on another domain
X-XSS-Protection- Enables the browser’s built-in Cross-Site Scripting (XSS) protection
X-Content-Type-Options: Stops the browser from trying to guess what content-type a response is (Content Sniffing) and forces it to use the
Strict-Transport-Security- If you’ve decided to make your site HTTPS only, setting the
Strict-Transport-Securityheader which means the browser will enforce HTTPS for you. You can read more on STS on Scott Helme’s site
Content-Security-Policy- Define a list of approved sources of content that a browser can load, good for preventing XSS attacks. https://report-uri.io/ will help you generate the content for this header.
It’s also a good idea to unset the
server header. Knowing what server your site is running on makes attacking it easier.
It may be fiddly to get your app to respond correctly with these headers, especially for static files that may not run through you app code pipeline. Or perhaps your site consists of multiple applications and you’d have to replicate your code across all the apps. It’s much easier to implement in VCL:
This is something you don’t want to have to worry about in your app code, as it’s a redundant request making it all the way to your webserver just to be told to come back and try again. Shielding your server from this kind of redundancy is just what varnish is for.
Let’s start with the code
So all this is doing is checking if the request has an
X-Forwarded-Proto header of
https and if it doesn’t return a synthetic response (i.e. one that wasn’t proxied from a backend, but was generated synthetically by varnish) of a 301 redirect to the HTTPS version of the url requested.
You may want to block access to you webserver for certain types of requests. Maybe you have a misbehaving bot that is hitting your site, it’s not respecting your
robots.txt and going places it shouldn’t or hitting you too often.
Similar to the way we enforced HTTPS, we can immediately block requests we don’t like using
We don’t need to customise the response headers, so the additional
vcl_synth call was not needed. Obviously this is not going to stop malicious attackers, but it can be useful to stop unintentionally misbehaving bots.
This is just a start as far as security for your site is concerned but it can help stop a lot of the more common attacks on your users. Why not setup a section.io account and see just how easy it can be to get Varnish running in front of your website.