September 23, 2016
5 min read time

How to get started with Varnish Cache 5.0 with experimental HTTP/2 support

Varnish Cache 5.0 is now available. In Varnish Cache 5.0 there is experimental support for HTTP/2. By "experimental" we mean that it works, but we haven't had any big production sites on it yet. We are eager for you to use it, test it and get your hands dirty with it and to get your input.
 
Here is how you enable it: 
 
1) Install Varnish Cache 5.0.0.
2) Install Hitch TLS proxy (www.hitch-tls.org) with ALPN support for terminating client TLS.
3) Configure ALPN, PROXYv2 and finally HTTP/2!
 
First up: Install Varnish Cache 5.0.0
 
Starting from 5.0, Varnish Cache is packaged in a single .deb file for Debian and Ubuntu systems.
 
   # dpkg -i varnish.deb
 
This should install or upgrade your current Varnish version to the new 5.0 version.
 
If you're running Enterprise Linux, there are EL6 and EL7 RPMs in the same pkg/ directory.
 
Install Hitch
 
Hitch is protocol-agnostic TLS terminating proxy, which sits in front of Varnish and does the
encryption when talking HTTPS to clients.
 
Installation of Hitch is best described in the Hitch documentation.
 
Hitch is also available in EPEL7 and Debian testing, but the versions may not be recent enough
to include the ALPN support.
 
Add some configuration
 
HTTP/2 support in Varnish is disabled by default, so you must add a feature flag to enable it. This
is done by passing  "-p feature=+http2" as a startup argument to Varnish. This is done in DAEMON_ARGS in /etc/default/varnish or in your systemd service file.
 
You can check if it is enabled by running varnishadm param.show feature
 
screenshot-http2-feature.png
 
 
Now we have a Varnish server that can speak HTTP/2 in clear text, but browsers prefer it to happen over HTTPS. So we need to run Hitch to decrypt TLS and let it pass the content to Varnish.
 
A minimal hitch.conf:
 
frontend = "[*]:443"
backend = "[127.0.0.1]:6086"
alpn-protos = "h2,http/1.1"
pem-file = "/etc/hitch/letsencrypt.pem"
ciphers = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
user = "hitch"
group = "hitch"
write-proxy = on
 
 
(making of keys and getting a certificate for the PEM-file is a bit complicated; see the hitch documentation linked earlier for details)
 
The important part is "alpn-protos" which is new in Hitch 1.4.0. This adds a hint when responding to browsers supporting HTTP/2 that it is safe to speak HTTP/2 to us.
 
The "backend" and "write-proxy" stances means that the communication between Hitch and Varnish will include a short preamble explaining who the client is, and what protocol it wants to speak. This is different from normal HTTP, so Varnish will need a separate listening socket for it. Add -a 127.0.0.1:6086,PROXY to enable this in Varnish.
 
At this stage, after restarting Hitch, you should be good to go.
 
Let us try a simple GET over HTTP2:
 
$ nghttp -v https://localhost/  
[  0.023] Connected
The negotiated protocol: h2
[  0.029] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
          (niv=2)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[..]
 
And the same request in seen on the Varnish side:
 
*   << Request  >> 65577     
-   Begin          req 65576 rxreq
-   Timestamp      Start: 1473948163.323900 0.000000 0.000000
-   Timestamp      Req: 1473948163.323900 0.000000 0.000000
-   ReqProtocol    HTTP/2.0
-   ReqStart       192.0.2.10 47900
-   ReqMethod      GET
-   ReqURL         /
-   ReqProtocol    HTTP/2.0
-   ReqHeader      scheme: https
-   ReqHeader      host: localhost
-   ReqHeader      accept: */*
-   ReqHeader      accept-encoding: gzip, deflate
-   ReqHeader      user-agent: nghttp2/1.14.0
[..]
 
There it is, we have a HTTP/2 enabled Varnish server!