summaryrefslogtreecommitdiff
path: root/content/posts/2022/2022-02-20-nginx-tls.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2022/2022-02-20-nginx-tls.md')
-rw-r--r--content/posts/2022/2022-02-20-nginx-tls.md92
1 files changed, 92 insertions, 0 deletions
diff --git a/content/posts/2022/2022-02-20-nginx-tls.md b/content/posts/2022/2022-02-20-nginx-tls.md
new file mode 100644
index 0000000..0baef43
--- /dev/null
+++ b/content/posts/2022/2022-02-20-nginx-tls.md
@@ -0,0 +1,92 @@
+---
+date: 2022-02-20
+title: Updating NginX TLS settings for 2022
+tags:
+- TLS
+- NginX
+---
+
+My blog (and pretty much every other site I host) is using Let's Encrypt
+certificates in order to be served over https. Using any certificate at all is
+generally an upgrade when it comes to security, but your webserver's
+configuration needs to be up to standard as well. Unlike the Let's Encrypt
+certificates, keeping the configs up to date requires manual intervention, and
+is therefore something I don't do often.
+
+This week I decided I should check up on the state of my SSL configuration in
+nginx. I usually check this through [SSL Lab's SSL Server
+Test](https://www.ssllabs.com/ssltest/analyze.html). This is basically
+[testssl.sh](https://testssl.sh/) in a shiny web frontend, and assigns you a
+score. I aim to always have A or higher, but it seemed my old settings were
+capped at a B. This was due to the cipher list allowing ciphers which are
+nowadays considered insecure.
+
+While I could've just updated the cipher list, I decided to check up on all the
+other settings as well. There's a [GitHub
+gist](https://gist.github.com/gavinhungry/7a67174c18085f4a23eb) which shows you
+what settings to use with nginx to make it secure by modern standards, which
+I've used to check if I should update some of my own settings.
+
+My old settings looked as follows. Please don't be too scared of the giant list
+in the `ssl_ciphers`.
+
+```nginx
+# DHparams
+ssl_dhparam /etc/nginx/dhparam.pem;
+
+# SSL settings
+ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
+ssl_prefer_server_ciphers off;
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_session_cache shared:le_nginx_SSL:10m;
+ssl_session_tickets off;
+ssl_session_timeout 1440m;
+
+# Additional headers
+add_header Strict-Transport-Security "max-age=63072000" always;
+```
+
+With the new settings, I've added `ssl_buffer_size` and `ssl_ecdh_curve`. A
+friend on IRC pointed out I should enable `ssl_prefer_server_ciphers`, so this
+has been enabled too.
+
+But most notably, the list of `ssl_ciphers` has been dramatically reduced. I
+still allow TLSv1.2 in order to allow slightly older clients to connect without
+any issues, but the ciphers considered *WEAK* have been disabled explicitly.
+This leaves a total of 5 ciphers to use, all of them using ECDHE, so the
+`ssl_dhparam` could be dropped as well.
+
+Lastly, I've added a couple headers for security reasons, as recommended by
+[securityheaders.com](https://securityheaders.com).
+
+```nginx
+# SSL settings
+ssl_protocols TLSv1.3 TLSv1.2;
+
+ssl_buffer_size 4K;
+ssl_ecdh_curve secp521r1:secp384r1;
+ssl_prefer_server_ciphers on;
+ssl_session_cache shared:le_nginx_SSL:2m;
+ssl_session_tickets off;
+ssl_session_timeout 1440m;
+
+ssl_ciphers 'EECDH+AESGCM:EECDH+AES256:!ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES256-SHA';
+
+# Additional headers
+add_header Content-Security-Policy "default-src 'self'" always;
+add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+add_header Strict-Transport-Security "max-age=63072000" always;
+add_header X-Content-Type-Options "nosniff" always;
+add_header X-Frame-Options "SAMEORIGIN" always;
+```
+
+{{< admonition title="note" >}}
+I would still like the `ssl_ciphers` to be formatted in a more clean way, which
+I've tried to do with a variable through `set`, but it appears variables are not
+expanded within `ssl_ciphers`. If you have any methods to format the list of
+ciphers used in a cleaner way, I'd be very happy to know!
+{{< / admonition >}}
+
+This configuration is saved as a small snippet which I `include` in all other
+site configurations, so it is updated everywhere at once as well. Now I should
+be able to neglect this for another year or two again.