HSTS (with Nginx) does not work properly

January 17, 2018 1.3k views
Security Django Nginx Ubuntu 16.04

I want to add HSTS to my Mezzanine 4.2.3 site. Using Nginx 1.10.3 and Ubuntu 16.04.

If I take add_header Strict-Transport-Security "max-age=60; includeSubDomains" always; out of the code below, the site works well, and visitors are always sent over to HTTPS.

However, adding the HSTS code makes it work intermittently. Sometimes it goes to HTTPS, but mostly it breaks and says the site is insecure.

server {
listen 80;
server_name *.example.com;
location / {
    rewrite ^ https://example.com;

server {
server_name <droplet ip address> example.com;
listen 443 ssl;

# managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

# Redirect non-https traffic to https
if ($scheme != "https") {
    return 301 https://$host$request_uri;
} # managed by Certbot

add_header Strict-Transport-Security "max-age=60; includeSubDomains" always;

location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
    root /home/example;

location / {
    include proxy_params;
    proxy_pass http://unix:/home/example/example.sock;

I've read Adding HSTS to nginx config and Best nginx configuration for improved security(and performance), as well as Nginx's own HTTP Strict Transport Security (HSTS) and NGINX.

Based on these articles, I think the code is ok. But I'm not sure. I've got the redirect to HTTPS (handled by Certbot), the SSL cert, and the HSTS header.

What have I missed?

Be the first one to answer this question.