--- 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.