ScaleScaleScaleScale

Tips / Nginx


How to configure HSTS on Nginx

Yesterday talking with one of the Nginxtips.com users about HTTPS I saw he mentioned he had enabled ‘HSTS’, so I started digging what was all that about… And it turns to be a great security tip for all those who use SSL certificates on their websites.

HTTP Strict Transport Security (aka HSTS) allows a website to enforce the SSL usage on the client side. HSTS let the browser know that it will only use HTTPS protocol, and this will lead into a better security to stop various kinds of man in the middle attacks. The way it works in simple words is: the remote server returns the HSTS header, browser pick up the HSTS header and from that time it will start forcing the SSL usage for the time specified in the ‘max-age’ that was set in the header.

How can I enable HSTS using Nginx?

As simple as adding a new response header in your virtual host configuration for the SSL websites you have, example:

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

On a server block it will look like:

server {
access_log off;
log_not_found off;
error_log  logs/yoursite-error_log warn;

        listen xx.xx.xx.xx:443 ssl spdy;
        server_name  www.yoursite.com;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

Explanation:

‘max-age’ variable specifies how long (seconds) you will be forcing your clientes to use HTTPS instead of HTTP, on this example I specified 1 year.

‘includeSubdomains’ option is just to ensure all your subdomains are also forced to use HTTPS.

How can I check HSTS is working?

With our all powerful and beloved curl command:

[user@server ~]$ curl -I https://www.yoursite.com -k
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 07 Nov 2014 11:38:19 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Pingback: https://www.yoursite.com/xmlrpc.php
Strict-Transport-Security: max-age=31536000; includeSubdomains

If you see Strict-Transport-Security: max-age=31536000; includeSubdomains, then HSTS is working as expected.

Having HSTS is very useful, however, you should always place a 301 URL redirect from HTTP to HTTPS to ensure all the content is redirected on the server side.

Popular search terms:

  • nginx hsts
  • enable HSTS nginx
  • nginx proxy No HSTS header is present on the response
  • hsts nginx
profile

Esteban Borges

Linux Geek, Webperf Addict, Nginx Fan. CTO @Infranetworking

  • Don’t forget HSTS preload 🙂 https://hstspreload.appspot.com

  • Nice writeup. To add the HSTS preload you need to edit your virtual host config and modify the line:
    add_header Strict-Transport-Security "max-age=31536000;includeSubdomains"; to resemble like this:
    add_header Strict-Transport-Security "max-age=31536000;includeSubdomains; preload";

    Then issue a service nginx reload and add the domain name (without subdomains) to the URL submitted by Hans previously. Easy peasy.