Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/core/compatibility/8.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff
| ----------------------------------------------------------------------- | ----------------- |
| ['ca-certificates' package removed from Alpine images](containers/8.0/ca-certificates-package.md) | Binary incompatible |
| [Debian container images upgraded to Debian 12](containers/8.0/debian-version.md) | Binary incompatible/behavioral change |
| [Debian container images no longer support TLS 1.2](./containers/8.0/default-ciphers-for-tls-changed.md) | Behavioral change |
| [Default ASP.NET Core port changed to 8080](containers/8.0/aspnet-port.md) | Behavioral change |
| [Kerberos package removed from Alpine and Debian images](containers/8.0/krb5-libs-package.md) | Binary incompatible |
| ['libintl' package removed from Alpine images](containers/8.0/libintl-package.md) | Behavioral change |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: "Debian 12 container images no longer support TLS 1.2"
description: Learn about the breaking change in containers where .NET 8 Debian container images no longer support TLS 1.2.
ms.date: 08/29/2024
---
# Debian 12 container images no longer support TLS 1.2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not true.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our default ciphersuite list allows any TLS 1.3 ciphersuite, and 8 TLS 1.2 ciphersuites.

The TLS 1.2 ciphersuites we allow aren't particularly esoteric, so it should be the case that we can, by default, talk to any TLS 1.2 endpoint.

Even if the default security level is non-zero, we still shouldn't be boxing out TLS 1.2:

$ openssl ciphers -s -stdname "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
TLS_AES_256_GCM_SHA384                        - TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256                  - TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256                        - TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       - ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         - ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       - ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       - ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         - ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         - ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA256

$ openssl ciphers -s -stdname "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:@SECLEVEL=0"
TLS_AES_256_GCM_SHA384                        - TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256                  - TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256                        - TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       - ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         - ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       - ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       - ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         - ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         - ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA256

$ openssl ciphers -s -stdname "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:@SECLEVEL=2"
TLS_AES_256_GCM_SHA384                        - TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256                  - TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256                        - TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       - ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         - ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       - ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       - ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         - ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         - ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA256

$ openssl ciphers -s -stdname "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:@SECLEVEL=5"
TLS_AES_256_GCM_SHA384                        - TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256                  - TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       - ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         - ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA384

That shows that OpenSSL 3.0.2 on Ubunutu 22.04 interprets our list as the same at the implicit security level, level 0, and level 2. By level 5 it is reduced, but still contains TLS 1.2 in the compatible protocols.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is true is that, by default, SSL3, TLS 1.0, and TLS 1.1 are all no longer supported.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, why do you think this results in a breaking change, then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Debian 11 included

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2

That includes a lot more ciphersuites. Plus, we don't (I believe) respect MinProtocol, if someone calls using SslProtocols.None then we map that to (again, I believe) TLS 1.0, 1.1, 1.2, and 1.3. That means that Debian 11 used a config like

$ openssl ciphers -s -stdname "DEFAULT@SECLEVEL=2"
TLS_AES_256_GCM_SHA384                        - TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256                  - TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256                        - TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384           - DHE-RSA-AES256-GCM-SHA384      TLSv1.2 Kx=DH       Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   - ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2 Kx=ECDH     Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     - DHE-RSA-CHACHA20-POLY1305      TLSv1.2 Kx=DH       Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       - ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         - ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256           - DHE-RSA-AES128-GCM-SHA256      TLSv1.2 Kx=DH       Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       - ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         - ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA384
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256           - DHE-RSA-AES256-SHA256          TLSv1.2 Kx=DH       Au=RSA   Enc=AES(256)               Mac=SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       - ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         - ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256           - DHE-RSA-AES128-SHA256          TLSv1.2 Kx=DH       Au=RSA   Enc=AES(128)               Mac=SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA          - ECDHE-ECDSA-AES256-SHA         TLSv1   Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA1
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA            - ECDHE-RSA-AES256-SHA           TLSv1   Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA1
TLS_DHE_RSA_WITH_AES_256_CBC_SHA              - DHE-RSA-AES256-SHA             SSLv3   Kx=DH       Au=RSA   Enc=AES(256)               Mac=SHA1
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA          - ECDHE-ECDSA-AES128-SHA         TLSv1   Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA1
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA            - ECDHE-RSA-AES128-SHA           TLSv1   Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA1
TLS_DHE_RSA_WITH_AES_128_CBC_SHA              - DHE-RSA-AES128-SHA             SSLv3   Kx=DH       Au=RSA   Enc=AES(128)               Mac=SHA1
TLS_RSA_WITH_AES_256_GCM_SHA384               - AES256-GCM-SHA384              TLSv1.2 Kx=RSA      Au=RSA   Enc=AESGCM(256)            Mac=AEAD
TLS_RSA_WITH_AES_128_GCM_SHA256               - AES128-GCM-SHA256              TLSv1.2 Kx=RSA      Au=RSA   Enc=AESGCM(128)            Mac=AEAD
TLS_RSA_WITH_AES_256_CBC_SHA256               - AES256-SHA256                  TLSv1.2 Kx=RSA      Au=RSA   Enc=AES(256)               Mac=SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256               - AES128-SHA256                  TLSv1.2 Kx=RSA      Au=RSA   Enc=AES(128)               Mac=SHA256
TLS_RSA_WITH_AES_256_CBC_SHA                  - AES256-SHA                     SSLv3   Kx=RSA      Au=RSA   Enc=AES(256)               Mac=SHA1
TLS_RSA_WITH_AES_128_CBC_SHA                  - AES128-SHA                     SSLv3   Kx=RSA      Au=RSA   Enc=AES(128)               Mac=SHA1

And the people who are observing breaks are the same people who cause Azure to keep deferring the "we're cutting off TLS 1.0 and 1.1... and we mean it this time" project.


.NET 8 Debian 12 container images use different default cipher suites for TLS than .NET 7 Debian 11 container images. The same is true for .NET 8 Ubuntu 24.04 containers images as compared to Ubuntu 22.04.

This change prevents applications from securely connecting to servers that don't support TLS 1.3.

.NET, on Linux, respects the OpenSSL configuration for default cipher suites when doing TLS/SSL via the <xref:System.Net.Security.SslStream> class or higher-level operations, such as HTTPS via the <xref:System.Net.Http.HttpClient> class. When default cipher suites aren't explicitly configured, .NET on Linux uses a tightly restricted list of permitted cipher suites. This behavior was [added in .NET 5 as a breaking change](../../cryptography/5.0/default-cipher-suites-for-tls-on-linux.md).

Debian 12 and Ubuntu 24.04 do not configure default cipher suites for OpenSSL. Alpine (all known versions) doesn't configure default cipher suites for OpenSSL.

## Previous behavior

.NET 6 and 7 Debian images are based on Debian 11. Debian 11 includes a setting in `/etc/ssl/openssl.cnf` that configures TLS 1.2 as the minimum supported protocol. This setting is honored by OpenSSL, including when used within .NET apps.

.NET 8 Ubuntu 22.04 images are configured the same way as Debian 11.

## New behavior

.NET 8 Debian images are based on Debian 12. Debian 12 does not configure a minimum protocol version in `/etc/ssl/openssl.cnf`. As a result, The .NET default ciphers are used on Debian 12 or higher, making TLS 1.3 the minimum protocol version.

.NET 8 Ubuntu 24.04 images are configured the same way as Debian 12 and also set TLS 1.3 as the minimum protocol version.

## Version introduced

.NET 8 container images

## Type of change

This change is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

Debian and Ubuntu maintainers presumably made this change to align with industry standards. TLS 1.2 has not been considered secure for many years. The .NET 5 change was made for the same rationale.

## Recommended action

To create secure workflows, upgrade components that don't support TLS 1.3.

More information is available at [dotnet/dotnet-docker #6039](https://github.com/dotnet/dotnet-docker/issues/6039).

## Affected APIs

None.
4 changes: 4 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ items:
href: containers/8.0/ca-certificates-package.md
- name: Container images upgraded to Debian 12
href: containers/8.0/debian-version.md
- name: Container images no longer support TLS 1.2
href: containers/8.0/default-cipher-suites-for-tls-on-linux.md
- name: Default ASP.NET Core port changed to 8080
href: containers/8.0/aspnet-port.md
- name: Kerberos package removed from Alpine and Debian images
Expand Down Expand Up @@ -1258,6 +1260,8 @@ items:
href: containers/8.0/ca-certificates-package.md
- name: Container images upgraded to Debian 12
href: containers/8.0/debian-version.md
- name: Container images no longer support TLS 1.2
href: containers/8.0/default-cipher-suites-for-tls-on-linux.md
- name: Default ASP.NET Core port changed to 8080
href: containers/8.0/aspnet-port.md
- name: Kerberos package removed from Alpine and Debian images
Expand Down
Loading