HTTP Strict Transport Security (HSTS) can be implemented in two different ways:
1) HSTS by Setting HSTS Headers
Example for Nginx:
add_header Strict-Transport-Security "max-age=15768000; preload" always;
First time visitors will get this header and their browsers will redirect internally to HTTPS (see redirect 307 in your network tab, if you inspect the web site). Browsers are caching this HSTS for the given max-age and recurring visitors will use HTTPS if they request your site.
2) HSTS by Preload
For this you can use the service provided by the site https://hstspreload.org/
Here you can add a 2nd level domain (e.g. my-company.com) to a list mainstream browsers will use to load the website via HTTPS. Before you can add a site to this list, this site has to set proper HSTS headers.
Additionally you should consider following details:
- removing a domain from the list needs some time and you'd better avoid this
- preload includes all sub domains for this 2nd level domain (e.g. www.my-company.com, abc.my-company.com, printer.my-company.com)
- HTTP access to subdomains (e.g. for local print services) may not work anymore
- beside from above issues HSTS preloading accelerates the access to a website for first time visitors and improves it's security
Regarding redirecting HTTP to HTTPS traffic and HSTS I recommend following setup:
Nginx Virtual Host Config
# HTTPS server section
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.my-company.com;
# include SSL configuration
include mycompany-ssl.conf;
# web root path
root /var/www/www.my-company.com/htdocs;
# allow access to .well-known (PKI validation folder)
location ~ ^/\.well-known {
allow all;
}
...
}
# redirect HTTPS and non-www requests
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my-company.com;
# include SSL configuration
include mycompany-ssl.conf;
# web root path
root /var/www/www.my-company.com/htdocs;
# allow access to .well-known (PKI validation folder)
location ~ ^/\.well-known {
allow all;
}
# default redirect
location / {
return 301 https://www.$http_host$request_uri;
}
}
# redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name my-company.com www.my-company.com;
# web root path
root /var/www/www.my-company.com/htdocs;
# allow access to .well-known (PKI validation folder)
location ~ ^/\.well-known {
allow all;
}
# default redirect
location / {
return 301 https://$http_host$request_uri;
}
}
Nginx Include Config for SSL/TLS
ssl on;
ssl_protocols TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:!MD5:!RC4:!LOW:!MEDIUM:!CAMELLIA:!ECDSA:!DES:!DSS:!3DES:!NULL";
ssl_prefer_server_ciphers on;
# Create session ticket key: openssl rand -out /etc/nginx/ssl/session_ticket_key 48
ssl_session_ticket_key /etc/nginx/ssl/session_ticket_key;
# Create dhparam4096.pem: openssl dhparam -out /etc/nginx/ssl/dhparam4096.pem 4096
ssl_dhparam /etc/nginx/ssl/dhparam4096.pem;
ssl_ecdh_curve secp384r1;
# Enable SSL stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=1800s;
resolver_timeout 15s;
# set security headers (see http://securityheaders.io/ for more details)
add_header Strict-Transport-Security "max-age=15768000; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin" always;
# set certificate files
ssl_certificate /etc/letsencrypt/www.my-company.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/www.my-company.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/www.my-company.com/fullchain.pem;