Split from bug #804894. Let's introduce USE=hardened that changes the defaults to what Python upstream does today. This means: 1. setting a stronger default for cipher suites. 2. setting default minimal TLS version to 1.2. FWICS, we can change the cipher suite by patching SSL_DEFAULT_CIPHER_LIST in include/openssl/ssl.h. Python uses: /* Python custom selection of sensible cipher suites * @SECLEVEL=2: security level 2 with 112 bits minimum security (e.g. 2048 bits RSA key) * ECDH+*: enable ephemeral elliptic curve Diffie-Hellman * DHE+*: fallback to ephemeral finite field Diffie-Hellman * encryption order: AES AEAD (GCM), ChaCha AEAD, AES CBC * !aNULL:!eNULL: really no NULL ciphers * !aDSS: no authentication with discrete logarithm DSA algorithm * !SHA1: no weak SHA1 MAC * !AESCCM: no CCM mode, it's uncommon and slow * * Based on Hynek's excellent blog post (update 2021-02-11) * https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ */ #define PY_SSL_DEFAULT_CIPHER_STRING "@SECLEVEL=2:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM" I suppose we don't want to disable TLS < 1.2 entirely, just by default. I think the cleanest way would be to patch ssl/ssl_lib.c and set min_proto_version in SSL_CTX_new.
These seem like reasonable defaults. Using <TLS1.2 should require an explicit acknowledgement. The same for any weak cipher suites. As such, I recommend these be the defaults vice being placed behind the hardened USE flag. Is there some technical reason for not disabling <TLS1.2?
Well, I meant IUSE=+hardened, just to be clear. I proposed an USE flag, so that users can switch to the upstream defaults if they actually need to connect to some old servers.
(In reply to Michał Górny from comment #2) > Well, I meant IUSE=+hardened, just to be clear. I proposed an USE flag, so > that users can switch to the upstream defaults if they actually need to > connect to some old servers. Perfect. Thanks for clarifying :)
Changing these settings at compile time is probably a bad idea because this will affect ABI and will cause a lot of test failures. OpenSSL already supports config files and OpenSSL 3 improved this. See this example https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql/mysql-8.0.25-r1.ebuild?id=700b729873e986802aa8ab6da9901c02ce7961c7#n385 where I had to allow TLS1/1.1 for test suite. You can use this policy system to have different policies per application. Fedora (RHEL) is doing a lot with these policies already. They even have a `eselect`-like system to manage these policies. PS: Note that Ubuntu 20.04 already tried to enforce TLS 1.2 by default (see all the "how to set lower SSL security level" questions since then). Not sure about https://launchpad.net/ubuntu/+source/openssl/1.1.1l-1ubuntu1 -- sounds like they reverted this week at least for unstable.
(In reply to Thomas Deutschmann from comment #4) > Changing these settings at compile time is probably a bad idea because this > will affect ABI and will cause a lot of test failures. > > OpenSSL already supports config files and OpenSSL 3 improved this. See this > example > https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql/mysql-8.0.25-r1. > ebuild?id=700b729873e986802aa8ab6da9901c02ce7961c7#n385 where I had to allow > TLS1/1.1 for test suite. > > You can use this policy system to have different policies per application. > Fedora (RHEL) is doing a lot with these policies already. They even have a > `eselect`-like system to manage these policies. Then someone would have to patch Python not to override cipher list with the constant from OpenSSL, for a start.
(In reply to Michał Górny from comment #5) > (In reply to Thomas Deutschmann from comment #4) > > Changing these settings at compile time is probably a bad idea because this > > will affect ABI and will cause a lot of test failures. > > > > OpenSSL already supports config files and OpenSSL 3 improved this. See this > > example > > https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql/mysql-8.0.25-r1. > > ebuild?id=700b729873e986802aa8ab6da9901c02ce7961c7#n385 where I had to allow > > TLS1/1.1 for test suite. > > > > You can use this policy system to have different policies per application. > > Fedora (RHEL) is doing a lot with these policies already. They even have a > > `eselect`-like system to manage these policies. > > Then someone would have to patch Python not to override cipher list with the > constant from OpenSSL, for a start. Scratch that, they're doing it conditionally.
Ok, so I've came up with: ``` openssl_conf = hardened [hardened] ssl_conf = hardened_ssl [hardened_ssl] system_default = hardened_default [hardened_default] CipherString = @SECLEVEL=2:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM MinProtocol = TLSv1.2 MinProtocol = DTLSv1.2 ``` However, CipherString already causes a bunch of test failures in CPython. It's kinda weird given that normally they're setting the same cipher list after all.