SSL/TLS and HSTS

SSL everywhere is on its way.
Unfortunately, many applications were written for HTTP only and switching to HTTPs is not an easy and straight forward path. Read more here about impact of TLS offloading (when a third party tool perform TLS in front of your web application servers).

A mechanism called HTTP Strict Transport Security (HSTS) has been introduced through the RFC 6797.

HSTS main purpose is to let the application server to instruct the client it’s supposed to get connected only a ciphered and secured HTTPs connection when browsing the application.
It means that of course, that both the client and the server must be compatible…
That way, the application cookie is protected on its way from the client’s browser to the remote TLS endpoint (either the load-balancer or the application server). No cookie hijacking is possible on the wire.

HAProxy configuration for Strict-Transport-Security HTTP header

HSTS header insertion in server responses

To insert the header in every server response, you can use the following HAProxy directive, in HAProxy 1.5:
[sourcecode language=”text”]
# 16000000 seconds: a bit more than 6 months
http-response set-header Strict-Transport-Security max-age=16000000;\ includeSubDomains;\ preload;
[/sourcecode]

With the upcoming HAProxy 1.6, and thanks to William’s work, we can now get rid of these ugly backslashes:
[sourcecode language=”text”]
# 16000000 seconds: a bit more than 6 months
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
[/sourcecode]

Inserting HSTS header in HTTP redirects


When HAProxy has to perform HTTP redirects, it does in at the moment of the client request, through the http-request rules.
Since we want to insert a header in the response, we can use the http-response rules. Unfortunately, these rules are enabled when HAProxy get traffic from a backend server.
Here is the trick: we do perform the http-request redirect rule in a dedicated frontend where we route traffic to. That way, our application backend or frontend can perform HSTS insertion.

A simple configuration sniplet is usually easier to explain:
[sourcecode language=”text”]
frontend fe_myapp
bind :443 ssl crt /path/to/my/cert.pem
bind :80
use_backend be_dummy if !{ ssl_fc }
default_backend be_myapp

backend be_myapp
http-response set-header Strict-Transport-Security max-age=16000000;\ includeSubDomains;\ preload;
server s1 10.0.0.1:80

be_dummy
server haproxy_fe_dummy_ssl_redirect 127.0.0.1:8000

frontend fe_dummy
bind 127.0.0.1:8000
http-request redirect scheme https
[/sourcecode]

Links