What Is HSTS and How To Enable It on Nginx
What is HSTS
HSTS stands for HTTP Strict Transport Security. HSTS tells web browsers that they should always interact with the server over https.
We are increasingly seeing websites serving content over HTTPS. Normal https websites use 301 permanent redirect to redirect insecure http requests to https. For example, every time you type the following URL in the browser address bar,
http://www.linuxbabe.com
you will be redirected to
https://www.linuxbabe.com
This redirect is done on the server side. When the server receives http request, it sends back a message to the browser telling the latter that http request is dropped by the server and the browser needs to send a https request.
What HSTS does is it tells web browsers to internally redirect http requests to https in the future. So now the redirect is done on the browser side.
HSTS tells browsers to default to https when the user do not specify the protocol scheme. If www.linuxbabe.com is not HSTS enabled, then when a user enter the following in the address bar:
www.linuxbabe.com
The browser will first try to send a http request to the server.
If www.linuxbabe.com is HSTS enabled, then a user enter www.linuxbabe.com in the browser address bar, the browser will first try to send a https request to the server.
HSTS helps reduce one round trip time and server load, and at the same prevent man in the middle attack.
Enable HSTS on Nginx
Open your Nginx virtual host configuration file. In the server block add the following line:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
Like below:
server { listen 443 ssl; server_name www.linuxbabe.com; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; ......
Save and close the file. Then reload Nginx configuration.
sudo service nginx reload or sudo sytemctl reload nginx
Check if HSTS is Working
Google Chrome Developer Tools
In Google chrome, press F12 key to open up developer tools, click the network tab. Then enter your domain name with http scheme:
http://www.linuxbabe.com
You will see in the network tab the first http request is redirected internally by Google Chrome and it never goes on the wire. Status code 307 means internal redirect.
curl command
Issue the following command
curl -I https://yourdomain.com
You will see a Strict-Transport-Security header.
Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
securityheaders.io service
securityheaders.io is a free service that check your website to see if you site has security headers which includes Strict-Transport-Security header. It tells you what security header you site contains and what security headers you site is missing.
Trust on First Use
HSTS is great but there still a TOFU problem. TOFU stands for Trust on First Use. Let’s say you have never visit a site like baidu.com before. When you enter baidu.com in browser address bar, the browser will send a http request to baidu.com. baidu.com tells you browser to send a https requst. Then baidu.com respond with HTTP header which contains Strict-Transport-Security header and HTML page to your browser.
There’s still a http request going on the wire which can be exploited by man-in-the-middle attack. To address this issue and protect your website, you can preload HSTS policy in browser by submitting your website to https://hstspreload.appspot.com.