Wednesday, March 8, 2017

Setting up Strict Transport Security (HSTS) in NGINX under a Vagrant Box

Today we I going to show how to set up HTTP Strict Transport Security (HSTS) in NGINX to improve slightly the security of your webapp.

HTTPS (HTTP encrypted with SSL or TLS) makes very difficult for an attacker to intercept, modify, or fake traffic between a user and the website. HSTS seeks to deal with potential vulnerabilities by instructing the browser that a domain can only be accessed using HTTPS. Even if the user enters a plain HTTP link, the browser will strictly upgrade the connection to HTTPS.

Let's learn by doing setting up HSTS in an standard Vagrant box running NGINX.

First lets create a self-signed SSL certificate for our HTTPS connection to the vagrant box (by default there is only HTTP connection available).

1) Create the certificates directory

$ sudo mkdir YOUR_CONFIG_FOLDER/certs

2) Create the key, csr and certificate:

$ cd YOUR_CONFIG_FOLDER/certs/

# Generate a new private key
$ sudo openssl genrsa -out "devcert.key" 2048

# Generate a CSR using the private key for encryption. It is interesting to enter the server name in this step.
$ sudo openssl req -new -key "devcert.key" -out "devcert.csr"

3) Sign and generate the certificate devcert.crt

$ sudo openssl x509 -req -days 365 -in "devcert.csr" -signkey "devcert.key" -out "devcert.crt"


Now set up the HSTS:

1) Edit the available site you want to setup in the sites-available folder

$ sudo vi /etc/nginx/sites-available/YOUR_SITE

2) Add the lines

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

ssl_certificate     YOUR_CONFIG_FOLDER/certs/devcert.crt;
ssl_certificate_key YOUR_CONFIG_FOLDER/certs/devcert.key;

after the listen or server_name variables. It will look like that:

server {
    listen 443 ssl;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

ssl_certificate     YOUR_CONFIG_FOLDER/certs/devcert.crt;
ssl_certificate_key YOUR_CONFIG_FOLDER/certs/devcert.key;

    [...]
}

3) Save the changes and restart the nginx service

$ sudo service nginx restart

That's all. Now you should be able to see also the HSTS header in the server response:

Strict-Transport-Security:max-age=31536000; includeSubDomains