This is a runthrough of after installing nginx, some steps we can take to get a good score at websites like https://observatory.mozilla.org.

There will be various steps you can take to get an A rating from the various tools linked from there. Let’s first work from the items described at https://securityheaders.io.

Security Headers

On Ubuntu, we can install nginx-extras, allowing us to clear the Server header.

more_clear_headers Server;

add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'none'; style-src 'self'; script-src 'self'; frame-ancestors 'none';";
add_header Referrer-Policy no-referrer;

Here are some links to corroborate.

I imagine this block of items is relevant on both the http as well as the https block.

HTTPS

Let’s first just redirect http to https, with

return 301 https://$host$request_uri;

You can note the redirect with curl or curl -I.

Install Certbot for creating certificates, Certbot can be found at https://certbot.eff.org/. Then generate the certificate with the following.

sudo certbot --nginx --rsa-key-size 4096

Certbot will modify your nginx config. I think all you really need from there right now is the two lines.

ssl_certificate /etc/letsencrypt/live/<url>/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<url>/privkey.pem; # managed by Certbot

Now https should be functioning.

Strict Transport Security

To improve our score, we can add HSTS via,

add_header Strict-Transport-Security "max-age=15768000; preload";

This will indicate to browsers that this site should be required to always provide https, that is, for the next 182 days. If you’re just trying things out, consider postponing adding this setting, or testing with extra urls. The setting can be reset in some browsers, but the testing sites may not have an option to clear the setting.

We now have a pretty good score on https://securityheaders.io, as well as on the first results tab at https://observatory.mozilla.org. Let’s consider now the ratings on the second tab, “TLS Observatory”, as well as at the linked site, https://ssllabs.com.

ssllabs.com

The cheat sheet for getting all 100s on ssllabs.com is at https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide.

protocol support 100%

ssl_protocols TLSv1.2;

key exchange 100%

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

ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_ecdh_curve secp384r1;

cipher strength 100%

There are a lot of ciphers, and various ways to come up with a list. I ended up using the list described at https://cipherli.st, and making a small adjustment.

ssl_ciphers "AES256+EECDH:!SHA";

There is a man page at https://www.openssl.org/docs/man1.0.2/apps/openssl.html which describes how you could inspect the list with for example:

openssl ciphers cipherlist 'AES256+EECDH:!SHA'

I selected this combination because some of the ratings sites suggested to use the 256 there, and to use ECDHE and not DHE, and to not use SHA-1. This seemed to get me the best combination of ratings across the sites.

Stapling

To improve the score further, we use recommended stapling settings.

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;

Conclusion

The sites advise this does not mean your site is now secure. I think the intent is that it motivates new developers to consider some aspects of operating a web server they might not have previously.

I’m not sure if this tutorial is as complete as I sought to make it, I will have to review it again soon, and I might add a “total config” that relates all the steps via the contents of a single config file.