Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy and paste global default TLS cipher set from ssl-config.mozilla.org #9809

Merged

Conversation

Al2Klimov
Copy link
Member

which got more secure by now, but still overlaps with v2.13.x' set.

fixes #9808

which got more secure by now, but still overlaps with v2.13.x' set.
@Al2Klimov Al2Klimov added this to the 2.14.0 milestone Jun 28, 2023
@Al2Klimov Al2Klimov requested a review from julianbrost June 28, 2023 12:53
@cla-bot cla-bot bot added the cla/signed label Jun 28, 2023
@julianbrost
Copy link
Contributor

I did some tests on CentOS 7 with openssl-libs-1.0.2k and Icinga 2.13.7 with the cipher string changed in the configuration to do some compatibility checks.

First of all, Icinga Web (both monitoring and icingadb modules) were still able to communicate with the Icinga 2 API.

Effect of the changed cipher string on the result reported by sslscan:

@@ -27,12 +27,8 @@
 TLSv1.2 not vulnerable to heartbleed
 
   Supported Server Cipher(s):
-Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256
-Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
-Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve P-256 DHE 256
-Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve P-256 DHE 256
-Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384            
-Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256            
+Preferred TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
+Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256
 
   Server Key Exchange Group(s):
 TLSv1.2  128 bits  secp256k1
Full sslscan output for the default cipher string in Icinga 2.13.7
Version: 2.0.16
OpenSSL 3.1.1 30 May 2023

Connected to 10.27.2.157

Testing SSL server 10.27.2.157 on port 5665 using SNI name 10.27.2.157

  SSL/TLS Protocols:
SSLv2     disabled
SSLv3     disabled
TLSv1.0   disabled
TLSv1.1   disabled
TLSv1.2   enabled
TLSv1.3   disabled

  TLS Fallback SCSV:
Server supports TLS Fallback SCSV

  TLS renegotiation:
Session renegotiation not supported

  TLS Compression:
OpenSSL version does not support compression
Rebuild with zlib1g-dev package for zlib support

  Heartbleed:
TLSv1.2 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384            
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256            

  Server Key Exchange Group(s):
TLSv1.2  128 bits  secp256k1
TLSv1.2  128 bits  secp256r1 (NIST P-256)
TLSv1.2  192 bits  secp384r1 (NIST P-384)
TLSv1.2  260 bits  secp521r1 (NIST P-521)

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    4096

Subject:  jb-centos7.novalocal
Altnames: DNS:jb-centos7.novalocal
Issuer:   Icinga CA

Not valid before: Jun 28 13:31:10 2023 GMT
Not valid after:  Jul 29 13:31:10 2024 GMT
Full sslscan output for the cipher string proposed in this PR with Icinga 2.13.7
Version: 2.0.16
OpenSSL 3.1.1 30 May 2023

Connected to 10.27.2.157

Testing SSL server 10.27.2.157 on port 5665 using SNI name 10.27.2.157

  SSL/TLS Protocols:
SSLv2     disabled
SSLv3     disabled
TLSv1.0   disabled
TLSv1.1   disabled
TLSv1.2   enabled
TLSv1.3   disabled

  TLS Fallback SCSV:
Server supports TLS Fallback SCSV

  TLS renegotiation:
Session renegotiation not supported

  TLS Compression:
OpenSSL version does not support compression
Rebuild with zlib1g-dev package for zlib support

  Heartbleed:
TLSv1.2 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256

  Server Key Exchange Group(s):
TLSv1.2  128 bits  secp256k1
TLSv1.2  128 bits  secp256r1 (NIST P-256)
TLSv1.2  192 bits  secp384r1 (NIST P-384)
TLSv1.2  260 bits  secp521r1 (NIST P-521)

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    4096

Subject:  jb-centos7.novalocal
Altnames: DNS:jb-centos7.novalocal
Issuer:   Icinga CA

Not valid before: Jun 28 13:31:10 2023 GMT
Not valid after:  Jul 29 13:31:10 2024 GMT

So actually only 2 ciphers remaining on CentOS 7.

Also probably a bit weird that it now prefers AES128+SHA256 over AES256+SHA384. That could be an effect of the config generator setting/assuming ssl_prefer_server_ciphers off;.

@julianbrost
Copy link
Contributor

What's strange though: openssl ciphers on that machine has more overlap with that cipher string than just these two:

[root@jb-centos7 ~]# openssl ciphers -v | column -t | sort | grep -E "$(echo ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 | tr : '|')"
DHE-RSA-AES128-GCM-SHA256      TLSv1.2  Kx=DH          Au=RSA    Enc=AESGCM(128)    Mac=AEAD
DHE-RSA-AES256-GCM-SHA384      TLSv1.2  Kx=DH          Au=RSA    Enc=AESGCM(256)    Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AESGCM(128)    Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AESGCM(256)    Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH        Au=RSA    Enc=AESGCM(128)    Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH        Au=RSA    Enc=AESGCM(256)    Mac=AEAD

@julianbrost
Copy link
Contributor

Interesting, looks like we might be doing something strange here that somehow prevents some ciphers to be used.

Supported ciphers reported on my local Docker setup:

  Supported Server Cipher(s):
Preferred TLSv1.3  256 bits  TLS_AES_256_GCM_SHA384        Curve 25519 DHE 253
Accepted  TLSv1.3  256 bits  TLS_CHACHA20_POLY1305_SHA256  Curve 25519 DHE 253
Accepted  TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256        Curve 25519 DHE 253
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CHACHA20-POLY1305   Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384            
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256            

And on openssl s_server -cipher ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256 -cert /var/lib/icinga2/certs/master-1.crt -key /var/lib/icinga2/certs/master-1.key running in the same container (that's the cipher string Icinga 2 is using):

  Supported Server Cipher(s):
Preferred TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256        Curve 25519 DHE 253
Accepted  TLSv1.3  256 bits  TLS_AES_256_GCM_SHA384        Curve 25519 DHE 253
Accepted  TLSv1.3  256 bits  TLS_CHACHA20_POLY1305_SHA256  Curve 25519 DHE 253
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384     DHE 3072 bits
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CHACHA20-POLY1305   Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-GCM-SHA256     DHE 3072 bits
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384            
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256            

So interestingly, DHE-RSA-AES256-GCM-SHA384 and DHE-RSA-AES128-GCM-SHA256 are missing on my local Icinga 2 as well.

(That the ECDSA ciphers are missing is no surprise as the server has no such certificate.)

@julianbrost
Copy link
Contributor

Found the culprit: in OpenSSL, DH parameters have to be loaded explicitly to enable DHE ciphers. In OpenSSL ≥ 3.0, there's a convenient function called SSL_CTX_set_dh_auto to do that. However, for older versions, you have to fiddle around with SSL_CTX_set_tmp_dh instead and provide DH group parameters yourself.

Given that nobody seems to have missed the DHE ciphers, is it even worth bothering to fix this? A fix for OpenSSL ≥ 3.0 only would be trivial though (add a single call to SSL_CTX_set_dh_auto).

However, if DHE ciphers don't work anyways, they should probably not be included in the default cipher list as that's only misleading.

@julianbrost
Copy link
Contributor

Wait a second, maybe SSL_CTX_set_dh_auto is also available on older versions. At least my Docker build was successful and that's still Debian 11 using OpenSSL 1.1.1n, but that function is not listed on https://www.openssl.org/docs/man1.1.1/man3/

@Al2Klimov
Copy link
Member Author

However, if DHE ciphers don't work anyways, they should probably not be included in the default cipher list as that's only misleading.

As a dev I want to be able to just copy and paste like this on every major (RELEASE.md PR coming soon) and see via git diff whether something changed. Also, for security reasons, I'd do the opposite, especially if it's that easy:

A fix for OpenSSL ≥ 3.0 only would be trivial though (add a single call to SSL_CTX_set_dh_auto).

Also, your assumption

nobody seems to have missed the DHE ciphers

assumes that people knew they didn't have them. I, in contrast, guess this comment of yours has awakened sleeping dogs. (Hello @pdolinic!)

TL;DR

A fix for OpenSSL ≥ 3.0 only would be trivial though (add a single call to SSL_CTX_set_dh_auto).

Make it so!

@julianbrost
Copy link
Contributor

Wait a second, maybe SSL_CTX_set_dh_auto is also available on older versions. At least my Docker build was successful and that's still Debian 11 using OpenSSL 1.1.1n, but that function is not listed on https://www.openssl.org/docs/man1.1.1/man3/

Okay, looks like that function was added in 1.1 but only documented in 3.0.

@julianbrost
Copy link
Contributor

However, if DHE ciphers don't work anyways, they should probably not be included in the default cipher list as that's only misleading.

As a dev I want to be able to just copy and paste like this on every major (RELEASE.md PR coming soon) and see via git diff whether something changed.

Understandable. However, we also want to be sure that we don't end up with 1024 bit DH which isn't considered to be secure anymore. So we have to double check that this also results in sane behavior with older OpenSSL versions.

Also, for security reasons, I'd do the opposite, especially if it's that easy:

A fix for OpenSSL ≥ 3.0 only would be trivial though (add a single call to SSL_CTX_set_dh_auto).

What exactly are those security reasons?

Also, your assumption

nobody seems to have missed the DHE ciphers

assumes that people knew they didn't have them. I, in contrast, guess this comment of yours has awakened sleeping dogs.

I actually meant from a compatibility perspective. I don't know of any reports that some client couldn't connect because it supports none of the ciphers offered but would have supported the DHE ciphers. Given that the server cipher order is preferred, the DHE ciphers would only be used by clients that would have used the RSA key exchange ciphers before (those with neither DHE nor ECDHE in their name).

From a security perspective, the (guaranteed minimal) security level you get is determined by the worst allowed cipher. So this can't be improved by adding more.

@Al2Klimov
Copy link
Member Author

From a security perspective, the (guaranteed minimal) security level you get is determined by the worst allowed cipher. So this can't be improved by adding more.

Of course, in addition to adding any more secure cipher the user has to disable the less secure ones. The more secure ciphers are possible, the better.

What exactly are those security reasons?

See above. Also, if our new favourite config generator decides to decommission some more ciphers in the future, we can still copy&paste from it with a (large enough) overlap.

@julianbrost
Copy link
Contributor

From a security perspective, the (guaranteed minimal) security level you get is determined by the worst allowed cipher. So this can't be improved by adding more.

Of course, in addition to adding any more secure cipher the user has to disable the less secure ones. The more secure ciphers are possible, the better.

If that's your goal, the best option is to go with TLS 1.3 only, just as the Mozilla config generator does if you select the modern level. Anyways, that discussion is becoming irrelevant, as I've created #9811 already.

As a dev I want to be able to just copy and paste like this on every major (RELEASE.md PR coming soon) and see via git diff whether something changed.

Doing so will change the preferred/default cipher for Icinga 2 cluster connections from ECDHE-ECDSA-AES256-GCM-SHA384 to ECDHE-ECDSA-AES128-GCM-SHA256, which at least feels like an odd change. I am still undecided what to do with this.

You can make an argument that the key exchange will typically be performed with DHE 3072 bit or ECDHE over P-256 or X25519, which are considered to provide a security level roughly equivalent to a symmetric 128 bit cipher, so AES128 would be adequate.

On the other hand, that group is chosen by OpenSSL, so a library upgrade could result in a change to a higher security level. Also, for a TLS 1.3 handshake, TLS_AES_256_GCM_SHA384 is preferred over TLS_AES_128_GCM_SHA256, so it's also strange to have it the other way around for TLS 1.2.

@julianbrost
Copy link
Contributor

I suggest the following cipher string:

ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256

This equates to the following changes (position of DHE-RSA-AES128-GCM-SHA256 is moved, all others are actual insertions or deletions):

 ECDHE-RSA-CHACHA20-POLY1305
 ECDHE-ECDSA-AES128-GCM-SHA256
 ECDHE-RSA-AES128-GCM-SHA256
-ECDHE-ECDSA-AES256-SHA384
-ECDHE-RSA-AES256-SHA384
-ECDHE-ECDSA-AES128-SHA256
-ECDHE-RSA-AES128-SHA256
-DHE-RSA-AES128-GCM-SHA256
 DHE-RSA-AES256-GCM-SHA384
-AES256-GCM-SHA384
-AES128-GCM-SHA256
+DHE-RSA-CHACHA20-POLY1305
+DHE-RSA-AES128-GCM-SHA256

Rationale:

@Al2Klimov
Copy link
Member Author

suggest the following cipher string:

ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256

Compared to mine it just prefers x256 AES over x128: https://asciinema.org/a/ZOO9QVNGb5lm3ACd7rdPOUOvA?t=75

Reasonable.

@Al2Klimov Al2Klimov self-assigned this Jul 3, 2023
@Al2Klimov Al2Klimov removed the request for review from julianbrost July 3, 2023 13:28
@Al2Klimov Al2Klimov removed their assignment Jul 3, 2023
@Al2Klimov Al2Klimov requested a review from julianbrost July 3, 2023 13:38
@julianbrost
Copy link
Contributor

Now the cipher preference on CentOS 7 looks like this:

  Supported Server Cipher(s):
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256

So no more reordering of ECDHE-RSA-AES256-GCM-SHA384 and ECDHE-RSA-AES128-GCM-SHA256.

@julianbrost
Copy link
Contributor

And with a slightly more recent OpenSSL version (1.1.1n on Debian 11, i.e. our Docker images):

  Supported Server Cipher(s):
Preferred TLSv1.3  256 bits  TLS_AES_256_GCM_SHA384        Curve 25519 DHE 253
Accepted  TLSv1.3  256 bits  TLS_CHACHA20_POLY1305_SHA256  Curve 25519 DHE 253
Accepted  TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256        Curve 25519 DHE 253
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CHACHA20-POLY1305   Curve 25519 DHE 253
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve 25519 DHE 253
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384     DHE 3072 bits
Accepted  TLSv1.2  256 bits  DHE-RSA-CHACHA20-POLY1305     DHE 3072 bits
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-GCM-SHA256     DHE 3072 bits

Everything that's expected to be there is there (no ECDSA ciphers because there is no ECDSA certificate) and in a good order.

@julianbrost julianbrost enabled auto-merge July 3, 2023 14:11
@julianbrost julianbrost merged commit fe13b96 into master Jul 3, 2023
@icinga-probot icinga-probot bot deleted the reevaluate-and-update-default-tls-cipher-list-9808 branch July 3, 2023 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reevaluate and update default TLS cipher list
2 participants