By Alex Yang
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?
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hello,
In case someone stumbles upon this question, It seems that the issue is with the configuration of the HSTS header. The HSTS header is sent to the browser on the first request and instructs the browser to only access the website over HTTPS for the duration specified in the header. In your configuration, the max-age of the HSTS header is set to 60 seconds, which is a very short duration. This means that after 60 seconds, the browser will no longer enforce HTTPS and will allow HTTP access to the website.
To fix this issue, you should increase the duration of the max-age parameter in the HSTS header to a longer period, such as 31536000 seconds (1 year). You can also consider adding the preload parameter to the header, which will include your website in the HSTS preload list maintained by major browsers. This will ensure that even new visitors to your website will always access it over HTTPS, even if they have never visited your website before.
Here is the updated configuration with the changes to the HSTS header:
server {
listen 80;
server_name *.example.com;
return 301 https://example.com$request_uri;
}
server {
server_name <droplet ip address> example.com;
listen 443 ssl http2;
# 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
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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;
}
}
Note that I also updated the configuration to include the http2 parameter on the SSL listener, which enables HTTP/2 support. This should improve the performance of your website.
Hello,
In case someone stumbles upon this question, It seems that the issue is with the configuration of the HSTS header. The HSTS header is sent to the browser on the first request and instructs the browser to only access the website over HTTPS for the duration specified in the header. In your configuration, the max-age of the HSTS header is set to 60 seconds, which is a very short duration. This means that after 60 seconds, the browser will no longer enforce HTTPS and will allow HTTP access to the website.
To fix this issue, you should increase the duration of the max-age parameter in the HSTS header to a longer period, such as 31536000 seconds (1 year). You can also consider adding the preload parameter to the header, which will include your website in the HSTS preload list maintained by major browsers. This will ensure that even new visitors to your website will always access it over HTTPS, even if they have never visited your website before.
Here is the updated configuration with the changes to the HSTS header:
server {
listen 80;
server_name *.example.com;
return 301 https://example.com$request_uri;
}
server {
server_name <droplet ip address> example.com;
listen 443 ssl http2;
# 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
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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;
}
}
Note that I also updated the configuration to include the http2 parameter on the SSL listener, which enables HTTP/2 support. This should improve the performance of your website.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.