HTTP/2 SSL Offloading with Hitch and Varnish
HTTP/2 SSL Offloading with Hitch and Varnish
Since Chrome browsers showing you insecure warning on unencrypted websites soon, i will show you in this post how to setup HTTP/2 SSL Offloading with Hitch and Varnish in few easy steps.
Prerequisites:
- A working Varnish 5.1+ Setup with H2 and PROXY Protocol enabled
- OpenSSL 1.0.2+ that supports ALPN
- Functional Hitch Setup with alpn protos H2 enabled
- Texteditor (vi, joe, nano) of your choice
1. We start with the Hitch Setup
Open your /etc/hitch/hitch.cfg
and if not already done we first set secure SSL Ciphers and SSL Options which will give you an Grade A rating at SSLLabs:
ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" tls-protos = TLSv1.0,TLSv1.1,TLSv1.2 prefer-server-ciphers = on sni-nomatch-abort = on
2. Now we add our frontent include pem file to our Hitch config
frontend = "[ReplaceWithYourPublicIP]:443+/etc/hitch/certs/combined.yoursite_cert.pem"
Notes: Change the Bind IP, Cert Location that it matches your Setup.
3. Our complete hitch.cfg should now look like this
frontend = "[ReplaceWithYourPublicIP]:443+/etc/hitch/certs/combined.yoursite_cert.pem" ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" tls-protos = TLSv1.0,TLSv1.1,TLSv1.2 prefer-server-ciphers = on sni-nomatch-abort = on quiet = on backend = "[127.0.0.1]:6086" # 6086 is the default Varnish PROXY port. workers = 2 # number of CPU cores daemon = on #user = "nobody" #group = "nogroup" alpn-protos = "h2, http/1.1" write-proxy-v2 = on # Write PROXY heade
Note: Change workers that it matches your needs.
4. In the final step we will prepare Varnish to speak the PROXY and HTTP/2 Protocol
Open /etc/default/varnish
and extend the lines by PROXY
and feature=+http2
like shown bellow:
DAEMON_OPTS="-a ReplaceWithYourPublicIP:80 -a 127.0.0.1:6086,PROXY -T 127.0.0.1:6082 -f /etc/varnish/YourVCL.vcl -p feature=+http2 -p thread_pools=2 -p thread_pool_min=450 -p thread_pool_max=5000 -p syslog_cli_traffic=off -t 120 -S /etc/varnish/secret -s malloc,1G"
Modify your VCL and add the redirects to force HTTPS
Right after vcl 4.0;
line at the beginning of your vcl we enable std module first using: import std;
sub vcl_recv { # set x-forwarded-proto header to https if connections comes from Hitch SSL Proxy. if (std.port(local.ip) == 6086) { set req.http.X-Forwarded-Proto = "https"; } # force http://www.ispire.me to https://www.ispire.me if connections comes from HTTP (Port: 80) Listener. if ( req.http.host ~ "^(?i)www.ispire.me" && req.http.X-Forwarded-Proto !~ "(?i)https") { set req.http.x-redir = "https://www.ispire.me" + req.url; return(synth(301)); } # force http://ispire.me to https://www.ispire.me. if ( req.http.host ~ "^(?i)ispire.me") { set req.http.x-redir = "https://www.ispire.me" + req.url; return(synth(301)); } } sub vcl_synth { if (resp.status == 301) { set resp.http.Location = req.http.x-redir; return (deliver); } } sub vcl_hash { # Cache https seperately if (req.http.X-Forwarded-Proto) { hash_data(req.http.X-Forwarded-Proto); } }
Restart your Hitch and Varnish service and check your Logs for Errors.
Watch your Varnishncsa Access Log, Connections with HTTP/2 should contain “HTTP/2.0” and Fallback Clients: HTTP/1.1 now.
If all looks fine enjoy your new HTTP/2 capability!
If you are 100%ly sure that SSL setup is working, activate HSTS:
sub vcl_deliver { set resp.http.Strict-Transport-Security = "max-age=31536000"; }
Thank you!
I have an error when changing vcl:
Message from VCC-compiler:
Symbol not found: ‘std.port’ (expected type BOOL):
(‘/etc/varnish/default.vcl’ Line 55 Pos 9)
if (std.port(local.ip) == 6086) {
——–########———————
Running VCC-compiler failed, exited with 2
VCL compilation failed
I am using varnish 5.2.
Something changed in 5.2?
Thank you.
You have to enable std module first:
import std;
Put it right after
vcl 4.0;
in your vcl.Hello,
Do you have an idea on enable server push (on WordPress)?
I have successful installed varnish for https (thank you), I can see it is using http/2, but no push. I tried wordpress plugin for server push, no use.
Thank you.
You have to write your own HTTP/2 Server Push vcl since Varnish doesnt support Server Push nativetly.
Reasons you can find here: https://varnish-cache.org/docs/trunk/phk/spdy.html
I am hunting half a day, there are no ready info, some are outdated.
It is quite complicated for me: I have to wait someone else to write an updated version or a hint.
Hi, another question:
I found http://domain.com redirected to https://domain.com
But not http://www.domain.com to https
have you checked and set everything like in the howto?
See block: “Force http://www.ispire.me to https if connections comes from HTTP Listener.”
That should redir http://www.ispire.me to https if http://www.ispire.me matches and x-forwarded-proto is NOT “https”.
Yes, only works in domain.com.
Perhaps it is a bug of Varnish 5.2.0?
On my setup it works fine with that settings.
Thank you, Jules, for offering personal help!
It is ok now, due to my misconfiguration.
If one day later, you install server push on ispire.me, please share it again, 🙂
Many thanks again….