How can I decide which ssl_protocols and ssl_ciphers to set with nginx?

7,181

There's no single correct answer to this, because choosing the cipher suites must be a suitable compromise between security and compatibility. The Mozilla's Server Side TLS Guidelines linked on the configuration generator explains the purpose for the different profiles:

  • Modern compatibility. For services that don't need backward compatibility, the parameters below provide a higher level of security. This configuration is compatible with Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8.

  • Intermediate compatibility (default). For services that don't need compatibility with legacy clients (mostly WinXP), but still need to support a wide range of clients, this configuration is recommended. It is is compatible with Firefox 1, Chrome 1, IE 7, Opera 5 and Safari

  • Old backward compatibility. This is the old ciphersuite that works with all clients back to Windows XP/IE6. It should be used as a last resort only.

Adding TLS 1.3 to these recommendations has been under discussion, but hasn't yet been added. This reasoning is from 2016, before TLS 1.3 was proposed as a standard in RFC 8446:

jvehent on Dec 27, 2016 Contributor

I don't think we should recommend experimental versions here. We waited for CHACHA20 to be standardized before adding it to the guidelines, the same applies to TLS1.3.

Likewise, Qualys SSL Labs has published SSL and TLS Deployment Best Practices. As it was (as of Jun 2019) last updated in May 2017, it also mentions TLS 1.3 only as a future protocol, but it explains the problems with older versions prior TLS 1.2:

TLS v1.2 should be your main protocol because it's the only version that offers modern authenticated encryption (also known as AEAD). If you don't support TLS v1.2 today, your security is lacking.

In order to support older clients, you may need to continue to support TLS v1.0 and TLS v1.1 for now. However, you should plan to retire TLS v1.0 in the near future. For example, the PCI DSS standard will require all sites that accept credit card payments to remove support for TLS v1.0 by June 2018.

Work is currently under way to design TLS v1.3, with the aims to remove all obsolete and insecure features and to make improvements that will keep our communication secure in the following decades.

The SSL Labs Server Test is updated more regularly and points out additional possible weaknesses:

  • All TLS_RSA ciphersuites have been marked as WEAK because they don't provide forward secrecy: if the private key gets compromised in the future, all recorded traffic can be decrypted using it.
  • All ciphersuites utilizing Cipher Block Chaining CBC aren't automatically weak, but there have been so many implementations vulnerable to padding oracle attacks that they have decided to mark them all as WEAK.

We also have a best current practice RFC 7525 from May 2015; Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS). Its section 4.2 gives recommendations that are similar to Mozilla's modern compatibility and SSL Labs Server Test:

Given the foregoing considerations, implementation and deployment of the following cipher suites is RECOMMENDED:

  • TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  • TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

These cipher suites are supported only in TLS 1.2 because they are authenticated encryption (AEAD) algorithms [RFC5116].

Based on all this it might be just fine to "tweak to your needs" the modern profile by e.g.

  • removing CBC based ciphersuites from the Modern compatibility profile i.e remove ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES256-SHA384, ECDHE-ECDSA-AES128-SHA256, ECDHE-RSA-AES128-SHA256
  • adding DHE ciphersuites as long as they have key length of at least 2048 bits and use GCM mode: DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES128-GCM-SHA256.

The Handshake Simulation section in SSL Labs Server Test helps pointing out the browsers that the configuration doesn't support. It's up to you to decide whether it's important to support them or not, and add the strongest ciphersuite available on that browser.

Whether to wait for Mozilla's recommendation on implementing TLS 1.3 or not is also opinion based. Good news for you is that TLS 1.3 has completely removed support for all legacy algorithms, making it harder to pick bad ciphersuites. From RFC 8446, 1.2. Major Differences from TLS 1.2:

The list of supported symmetric encryption algorithms has been pruned of all algorithms that are considered legacy. Those that remain are all Authenticated Encryption with Associated Data (AEAD) algorithms. The cipher suite concept has been changed to separate the authentication and key exchange mechanisms from the record protection algorithm (including secret key length) and a hash to be used with both the key derivation function and handshake message authentication code (MAC).

Share:
7,181

Related videos on Youtube

Martin Thoma
Author by

Martin Thoma

I also have a blog about Code, the Web and Cyberculture and a career profile on Stackoverflow. My interests are mainly machine-learning, neural-networks, data-analysis.

Updated on September 18, 2022

Comments

  • Martin Thoma
    Martin Thoma over 1 year

    I recently added TLS (letsencrypt with certbot) to my domain. It comes with a basic configuration options-ssl-nginx.conf which includes

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    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";
    

    This part is identical to what Mozilla recommends.

    Then I checked my domain with https://ssldecoder.org and . They complained that my server does not support TLSv1.3

    Question 1: Why is TLSv1.3 not in ssl_protocols? Is there any reason not to add it?

    Checking my site with https://www.ssllabs.com/ssltest shows some complaints about supported SSL ciphers:

    • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    • TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
    • TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    • TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
    • TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    • TLS_RSA_WITH_AES_128_GCM_SHA256
    • TLS_RSA_WITH_AES_256_GCM_SHA384
    • TLS_RSA_WITH_AES_128_CBC_SHA256
    • TLS_RSA_WITH_AES_256_CBC_SHA256
    • TLS_RSA_WITH_AES_128_CBC_SHA
    • TLS_RSA_WITH_AES_256_CBC_SHA

    Question 2: How should I decide which ciphers to support?

    If less ciphers are supported, less devices will be able to reach the site. But is there a way for me to judge how many that will be (something like caniuse.com for css, but for ciphers)? And, as this is the order of preference and the client can still take anyone they like: Why should I not support all?