vertner.net

New and Improved With SSL - Update

Alright, so it took some tooling around and a better understanding of Nginx, my web server application, but I got some issues sorted out. I was getting frustrated that running my site through Qualys’ excellent SSL Labs tool kept showing that I still supported SSLv3, despite removing that from my SSL information in my server blocks. Possibly due to some of my redirection shenanigans, some ways a user might probe my site after setting up ssl still resulted in offering SSLv3 services. Ultimately, what worked was to go up a level: to the /etc/nginx/nginx.conf configuration file. Essentially, what Nginx is doing is running that configuration file and nested within its http block is an include for /etc/nginx/sites-enabled/*, which essentially just dumps all of your server blocks in there.

Game changer. After hours of research, I simply moved all of my SSL info up into my http block in the main configuration file. Additionally, since there’s no such thing as bad research, I did some more reading on server security and came up with some extra layers of awesomeness. First thing I did was beef up the cipher usage with a strong preference towards Forward Secrecy and Ephemeral Diffie-Hellman. To do so effectively, however, I needed to generate a stronger Diffie-Hellman parameter by typing the following:

1
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

This dumped a new certificate file in with the rest of the certificates the site is referencing. Why is this necessary? Because good encryption starts with big prime numbers.

Next, I told Nginx to look for by adding the following to our http block:

1
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

Next, I wanted to add OCSP (Online Certification Status Protocol) Stapling and prevent potential denial-of-service attacks by offering clients a cached copy of my OCSP response in lieu of going to a third party. That was as simple as adding the following:

1
2
3
4
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

Finally, I implemented HSTS (HTTP Strict Transport Security), which instructs browsers to only communicate with the server via HTTPS. Given the 301 redirects I’m always employing in my configuration, this is redundant, but it’s a better practice.

1
2
3
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

Taken together, this is what I’ve got:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#The HTTPS configuration

ssl_certificate /etc/nginx/ssl/ssl-unified.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM$
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_session_tickets off;

# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

#The rest of my settings...

… and the results are positive! Now the site has an A+ and has never been more secure. Special thanks to Remy van Elst and his excellent primer on secure Nginx configuration.

Even better!Even better!

Comments