7

I have created an nginx config that got a perfect score on Qualsys SSL Labs using only TLS v1.2, and I'd like to try and get a perfect score using both TLS v1.2 and v1.3.

Consider this snippet of the version of the nginx.conf that is part of the A+ and 100% score:

ssl_protocols TLSv1.2;
ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;

It complains about a couple of the cipher suites, but it still gives an otherwise perfect score:

enter image description here enter image description here

Now, if I add TLS v1.3 to the mix as the only config change, the score changes.

ssl_protocols TLSv1.2 TLSv1.3;

The cipher strength gets scored as a 90%: enter image description here

I assume it's mad about those weak CBC ciphers:

TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)   ECDH secp384r1 (eq. 7680 bits RSA)   FS   WEAK 256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   ECDH secp384r1 (eq. 7680 bits RSA)   FS   WEAK    256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b)   DH 4096 bits   FS   WEAK   256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   DH 4096 bits   FS   WEAK

There's not really a good way to remove the CBC mode ciphers perfectly, but maybe excluding SHA1, SHA256, and SHA384 will work. The config line becomes:

ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL:!SHA1:!SHA256:!SHA384;

Let's look at the new score: enter image description here

The cipher suite strength is still 90%.

It's no longer mad at the strength of the cipher suites: enter image description here

But apparently it's unhappy about the failing handshakes that worked before: enter image description here

Which brings us to... the same cipher suites that are required for a successful handshake for older devices/apps are listed as "weak" and pass when only TLS 1.2 is enabled. Somehow enabling TLS 1.3 makes those same weak ciphers that pass before start failing.

It seems like the choice is: either enable TLS 1.2 only to get a perfect score, or, enable TLS 1.3 too but get dinged for the necessary cipher suites? It's a Kobayashi Maru of sorts.

Is it possible to get a perfect 100% score with nginx and TLS 1.2 and 1.3 enabled?

Gojira
  • 439
  • 2
  • 5
  • 10
  • I assume those bars and percentages don't mean very much. – Michael Hampton Aug 31 '19 at 01:39
  • I don't know what they "mean", but at least for now the SSL Labs test is considered some kind of standard. – Gojira Aug 31 '19 at 01:43
  • That doesn't mean you should blindly trust the top line and ignore all the results. There's no way it should be A+ 100% with weak ciphers listed. There is probably a bug that they need to fix. – Michael Hampton Aug 31 '19 at 01:48
  • I'm not blindly trusting anything, but I would like to know whether their own rules are consistent. – Gojira Aug 31 '19 at 01:53
  • 2
    Is your service made for SSL Labs or for the users? Instead of making the bars 100% you should be searching for a good compromise between maximum security and compatibility. [RFC 7525](https://tools.ietf.org/html/rfc7525) is a good starting point. – Esa Jokinen Aug 31 '19 at 05:20
  • https://wiki.mozilla.org/Security/Server_Side_TLS also provides good guidance (including config generator) – Håkan Lindqvist Aug 31 '19 at 08:49

3 Answers3

7

Regarding your actual question, which is about the Qualys SSL Labs test tool itself, we'll have to dig into how their rating system works.
Fortunately Qualys have published their SSL Server Rating Guide, which describes their methodology for rating SSL/TLS configurations.

As your question is about why you got a slightly lower score in the Cipher Strength category with one of your proposed configs over the other, let's focus on that category specifically:

Cipher Strength

To break a communication session, an attacker can attempt to break the symmetric cipher used for the bulk of the communication. A stronger cipher allows for stronger encryption and thus increases the effort needed to break it. Because a server can support ciphers of varying strengths, we arrived at a scoring system that penalizes the use of weak ciphers. To calculate the score for this category, we follow this algorithm:

  1. Start with the score of the strongest cipher.
  2. Add the score of the weakest cipher.
  3. Divide the total by 2.

Table 5. Cipher strength rating guide

Cipher strength               Score
0 bits (no encryption)        0%
< 128 bits (e.g., 40,56)      20%
< 256 bits (e.g., 128, 168)   80%
>= 256 bits (e.g., 256)       100%

Looking back at the more detailed results included in the question, we can see that in the TLS1.2-only config, you were using only 256 bit ciphers (even though some of the cipher suites were frowned upon), while in the TLS1.2+TLS1.3 config you were using a mix of 128 bit and 256 bit ciphers.
Based on their rating system, this explain why you got a reduced score in "Cipher Strength".

Now, this pretty much highlights that while this tool is a very useful resource (particularly to point out actual bad configurations), it's not a great idea to focus too much on the exact scoring, rather to look at the whole report.


As for what is actually a reasonable TLS setup, unless you have a strong idea of what you need, I would suggest looking at the Server Side TLS guidance maintained by Mozilla's Operations Security and Enterprise Information Security teams.
Particularly their "Intermediate" configuration strikes a good balance between broad compatibility and security, and there is a config generator for popular TLS servers for convenient translation of suggested settings into actual server configuration.

Håkan Lindqvist
  • 33,741
  • 5
  • 65
  • 90
  • Thanks. I realize that focusing on the score is useful only as an academic exercise, and in a "real world" implementation one must navigate tradeoffs between security and compatibility, convenience, etc. At any rate thanks for the explanation. – Gojira Aug 31 '19 at 15:21
  • so its not possible to have 100 score with tls1.2 + tls1.3 ? – lifeofguenter Sep 29 '19 at 12:24
4

It is possible at the cost of TLS1.3 compliance by configuring OpenSSL to exclude some ciphers for TLS 1.3 usage.

I wrote a short howto on it here:

TLS ALL The Things! detailing on how to achieve it plus enable minimum use of 112-bit equivalent for the rest of the OS.

Here you can see the result of the example running here

https://i.imgur.com/0g9B8cP.png

Note the use of CBC ciphers, normally you want to remove these as well and only run GCM. However, due to the amount of people visiting, you might take that risk instead of forcing everyone to run evergreen. (Go evergreen!)

Anyways, the part you are really interested in is:

Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
Options = ServerPreference,PrioritizeChaCha

By adding those to your OpenSSL configuration, you will effectively remove the 128 bit parameters... Nginx will still do TLS 1.2 configuration etc for you as that binary controls those settings instead of OpenSSL. The rest of your OS relying on the settings in OpenSSL will thereafter also use these! (warmly recommended)

kenlukas
  • 2,886
  • 2
  • 14
  • 25
  • Awesome! Thank you! – Gojira Nov 08 '19 at 14:39
  • It's not giving perfect score anymore :( I've tried the "no weak ciphers" `ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS_AES_256_GCM_SHA384:TLS-AES-256-GCM-SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;` – lewis4u May 05 '20 at 06:03
  • It should give a perfect score... The exact same config is running on all our customers servers/dockers and gives a nice 100%*4 Please double check both your OpenSSL and Nginx version and that you have configured OpenSSL (in /etc/ssl/openssl.cnf) as prescribed. – Angelique Dawnbringer May 06 '20 at 08:36
  • `openssl ciphers -v | grep 1.2 | grep -v 128 | grep 'Kx=ECDH' | grep -v 'PSK'` AND `openssl ciphers -s -v | grep 1.3` – Angelique Dawnbringer May 06 '20 at 09:01
1

Same in Apache:

Open console as root and edit /etc/letsencrypt/your-ssl.cnf
SSLEngine on SSLProtocol -all +TLSv1.2 +TLSv1.3 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA
Open console as root and edit /etc/ssl/openssl.cnf
root@vps# nano /etc/ssl/openssl.cnf
Add this rule in configfile for OpenSSL 1.1.1
CipherSuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256

Proof:

100% score

ComputerBas
  • 122
  • 7
  • 2
    This configuration violates [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446#section-9.1): "A TLS-compliant application MUST implement the TLS_AES_128_GCM_SHA256 [GCM] cipher suite". – Paul Jan 14 '22 at 21:24
  • August 2018... This is an ongoing process and if you want to score max on tls checkers leave this cipher behind. Its not needed for browser handshakes. – ComputerBas Jan 16 '22 at 17:52
  • The RFC is the current one, so the specific date on it is only to inform us of when it was published. There is not currently an RFC that supersedes it. To technically be in compliance with TLS version 1.3, the server MUST implement TLS_AES_128_GCM_SHA256. – Paul Jan 16 '22 at 19:23
  • Maybe it's time for a new RFC. Until then.. i guess you're right. – ComputerBas Jan 16 '22 at 20:09
  • 1
    Full question title: "Perfect SSL Labs score with nginx and TLS 1.3?" As we can easily read in the standard, which is where the term "TLS 1.3" is defined, you cannot get both. You EITHER be in compliance with the standard OR get a perfect score. Qualys can put a little flag stating the server is in compliance, but people who can read the standard know that Qualys has demonstrated unreliable by deciding to call something out of compliance as in compliance. – Paul Jan 16 '22 at 21:04