From 3789e0f66efb473bd486e9c17ac8d799f6e07a90 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Sun, 20 Feb 2022 11:33:14 +0100 Subject: Add post on updating nginx TLS configs --- content/posts/2022/2022-02-20-nginx-tls.md | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 content/posts/2022/2022-02-20-nginx-tls.md 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. -- cgit v1.1