SSL everywhere, HSTS and nginx
You may of noticed when browsing my blog or web site that your connection is set over SSL. This is done help reach the goal of HTTPS/SSL everywhere.
I have also enabled HSTS(HTTP Strict Transport Security) in an effort to avoid man in the middle SSL attacks With HSTS a header is sent via my web server to your browser called "Strict-Transport-Security", when your browser receives this header it will not permit any connections to be sent to my web server unencrypted. Even if you forget the "HTTPS" part I have set a redirect on my server to force you back over SSL/HTTPS.
So how hard was this all to do? Not hard at all! Lets take a look.
Firstly your going to need a SSL certificate. I use Namecheap for this. They use Comodo to issue the certificate. You can use any SSL issuer. If you have only one site, take a look at startSSL by StarCom they over free basic SSL certificates.
Next up configure nginx to use the SSL certificate.
For the blog your reading I use the following settings (in a server{} block) :
listen [::]:443;
listen 443;
server_name blog.horan.hk;
ssl on;
ssl_certificate /etc/nginx/ssl/blog.horan.hk/bundle.blog.horan.hk.crt;
ssl_certificate_key /etc/nginx/ssl/blog.horan.hk/blog.horan.hk.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;
This sets up a few things.
- Sets a list of allowed protocols and ciphers, after all we don't want things like SSL v3 enabled!
- Enable SSL stapling to help reduce overheads
- Sets location for SSL certificate, private key and DH parameters file.
Most import however for HSTS is this the last line "add_header"
- This line adds the header "Strict-Transport-Security" with a max age of one year, include all subdomains and always set the STS header.
Next we want to ensure all requests are over HTTPS so I set up a redirect for HTTP traffic like this :
server {
listen [::]:80;
listen 80;
server_name blog.horan.hk;
return 301 https://$server_name$request_uri;
}
This server{} block goes in the same file as the above server{} block.
Lastly you want to check that HSTS header is sent and understood by the client. For this I use FireFox's web dev tools inside the web browser. Looking at the image below you can see my client receives the HSTS headers.