You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The next version of the IETF-standardized TLS protocol is known as Encrypted ClientHello (ECH) [1] formerly known as Encrypted SNI (ESNI). This ticket collects information for ECH support, and tracks which APIs have to be added to Python in order to implement ECH in Python's ssl module. ECH is built on top of TLSv1.3 and completes the unfinished work from the TLSv1.3 effort. It is now in draft-13 and there are many implementations that are interoperating. ECH is working for openssl[2], boringssl[3], nginx, Apache HTTPD, lighttpd, HAProxy, Conscrypt[4], curl, and more. There is work underway in Firefox [5] and Chromium [6]. It has been sketched out for OkHTTP [7]. Early versions of the standard, known as ESNI, have been deployed in Firefox releases and some production web services. ECH works in conjunction with the new DNS RR Types HTTPS and SVCB [8]. This means that DNS needs to be handled a bit differently.
As far as I understand it, the ssl module has to gain additional features:
HTTPS/SVCB DNS queries for setting up TLS connection with ECH.
A way to provide ECH Config Lists as bytes directly to ssl clients.
A callback that gets called whenever ECH negotiation fails and the server offers a "Retry Config".
A method to ensure encrypted DNS is used so all metadata is encrypted.
OpenSSL does not implement the necessary APIs yet. Stephen Farrell's development OpenSSL fork [9] implements ECH and has been used in Apache HTTPD, nginx, lighttpd, HAProxy, and curl implementations.
The DNS lookup part is out of scope for the ssl module. I don't want to get into the DNS business. At $WORK I work on BIND, DNSSEC and DNS over TLS. Secure DNS (and DNS in general) is already complicated when you control the entire stack and only have to deal with one family of Linux distros. AFAIK there isn't even a platform-independent way to perform lookups with abitrary RRTYPEs. res_nquery() is only available on some platforms and doesn't work reliable with some libcs. I have had issues with EDNS0 on musl in the past. KRB5KDC SRV looks with large responses where unreliable. Let's offload the DNS part of consumers of the ssl module. They can use python-dns or c-ares.
The ECH part and callback look sensible, though. I'll include the APIs as soon as OpenSSL support them.
eighthave commented on Nov 2, 2021
eighthavemannequin
MannequinAuthor
More actions
I agree with all you say, but I think it is important to not rule out handling HTTPS/SVCB DNS here. It can happen at a later stage though. What you propose works great for the first step.
If handling the DNS is punted to some external library, that means that each client app will have to implement this itself, and its non-trivial. In that scenario, very few clients will implement it. This makes me believe that this should be implemented in the core. Granted, its an open question whether the ssl module is the right place. For example, it could makes more sense to handle HTTPS/SVCB DNS in the HTTP libs (urllib, requests, etc), but that means non-HTTP uses (XMPP, Matrix, etc) will be disadvantaged.
We (https://defo.ie/#contact@sftcd@jspricke@eighthave and others) have been funded again by Open Tech Fund to work on pushing ECH forward over the next 2+ years. We want to dive back in here and start implementing this. ECH support was accepted by OpenSSL as something they want to include, and our implementation is working its way through their process here: openssl/openssl#22938
We now have more implementations to draw experience and examples from. For example, there is a client-only rustls pull request: rustls/rustls#1718
I think the easiest starting point will be to expose the OpenSSL functions, then start work on supporting the client-side with urllib and requests (psf/requests#5972). How does that sound?
As part of the above mentioned Open Tech Fund work, I've got a working branch with support for setting ECH related options, and with the help of dnspython (to fetch the HTTPS/SVCB records) to establish ECH connections (client only). This uses the agreed API with the openssl maintainers and is currently on a feature branch in openssl.
My branch has been based on 3.13 although I'll be updating it this week to be based on main.
Hello everyone, quick update: The current source for the DEfO ECH project for cpython's SSL module is getting a full security audit through OSTIF.org. Additionally, we will be providing the fuzzing harnesses provided to the DEfO maintainers, with the intention that when the ECH patch gets accepted, it will have corresponding fuzz testing ready to go on ossfuzz for continuous dynamic testing.
Note that this is the CURRENT source and that if any API changes are built after our evaluation, we will need to revisit the project and review the diff to ensure that everything is sound and that we have as much test coverage as we can get for integration.
We have just completed a similar engagement with the DEfO integration of OpenSSL and it has gone well. The public report about this work will be released on our website in early 2026.
Hiya - I've updated the DEfO implementation to 3.15 (so as to match where debian are at for our test harness), but more or less the same changes seemed ok with the upstream latest when I checked that.
What's the best way to try get this ECH clien-side feature upstreamed? It's not very complex (indeed the whole thing is one smallish patch) in the debian build.
I'd be fine with creating a fresh PR for this, or processing it however best, if there's a realistic chance of it being upstreamed in the next while.
Note that the ECH spec is now RFC9849 and the ECH code required for this was part of the OpenSSL v4.0 release back in April this year, so I'd argue it's now mature enough to be upstreamed here.
Activity
eighthave commentedon Oct 22, 2021
The next version of the IETF-standardized TLS protocol is known as Encrypted ClientHello (ECH) [1] formerly known as Encrypted SNI (ESNI). This ticket collects information for ECH support, and tracks which APIs have to be added to Python in order to implement ECH in Python's ssl module. ECH is built on top of TLSv1.3 and completes the unfinished work from the TLSv1.3 effort. It is now in draft-13 and there are many implementations that are interoperating. ECH is working for openssl[2], boringssl[3], nginx, Apache HTTPD, lighttpd, HAProxy, Conscrypt[4], curl, and more. There is work underway in Firefox [5] and Chromium [6]. It has been sketched out for OkHTTP [7]. Early versions of the standard, known as ESNI, have been deployed in Firefox releases and some production web services. ECH works in conjunction with the new DNS RR Types HTTPS and SVCB [8]. This means that DNS needs to be handled a bit differently.
As far as I understand it, the ssl module has to gain additional features:
OpenSSL does not implement the necessary APIs yet. Stephen Farrell's development OpenSSL fork [9] implements ECH and has been used in Apache HTTPD, nginx, lighttpd, HAProxy, and curl implementations.
The TLS WG maintain a page with information about other implementations:
https://github.com/tlswg/draft-ietf-tls-esni/wiki/Implementations
[1] https://www.ietf.org/archive/id/draft-ietf-tls-esni-13.html
[2] openssl/openssl#7482
[3] https://bugs.chromium.org/p/boringssl/issues/detail?id=275
[5] https://bugzilla.mozilla.org/show_bug.cgi?id=1725938
[6] https://bugs.chromium.org/p/chromium/issues/detail?id=1091403
[6] google/conscrypt#730
[7] lysine-dev/okhttp#6539
[8] https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.html
[9] https://github.com/sftcd/openssl
tiran commentedon Oct 22, 2021
Thanks for filing this feature request!
The DNS lookup part is out of scope for the ssl module. I don't want to get into the DNS business. At $WORK I work on BIND, DNSSEC and DNS over TLS. Secure DNS (and DNS in general) is already complicated when you control the entire stack and only have to deal with one family of Linux distros. AFAIK there isn't even a platform-independent way to perform lookups with abitrary RRTYPEs. res_nquery() is only available on some platforms and doesn't work reliable with some libcs. I have had issues with EDNS0 on musl in the past. KRB5KDC SRV looks with large responses where unreliable. Let's offload the DNS part of consumers of the ssl module. They can use python-dns or c-ares.
The ECH part and callback look sensible, though. I'll include the APIs as soon as OpenSSL support them.
eighthave commentedon Nov 2, 2021
I agree with all you say, but I think it is important to not rule out handling HTTPS/SVCB DNS here. It can happen at a later stage though. What you propose works great for the first step.
If handling the DNS is punted to some external library, that means that each client app will have to implement this itself, and its non-trivial. In that scenario, very few clients will implement it. This makes me believe that this should be implemented in the core. Granted, its an open question whether the ssl module is the right place. For example, it could makes more sense to handle HTTPS/SVCB DNS in the HTTP libs (urllib, requests, etc), but that means non-HTTP uses (XMPP, Matrix, etc) will be disadvantaged.
eighthave commentedon Feb 7, 2024
We (https://defo.ie/#contact @sftcd @jspricke @eighthave and others) have been funded again by Open Tech Fund to work on pushing ECH forward over the next 2+ years. We want to dive back in here and start implementing this. ECH support was accepted by OpenSSL as something they want to include, and our implementation is working its way through their process here:
openssl/openssl#22938
We now have more implementations to draw experience and examples from. For example, there is a client-only rustls pull request:
rustls/rustls#1718
We have a Debian PPA for installing our ECH implementations in Apache, nginx, curl, and others. So it is now easy to have ECH running on test domains:
https://guardianproject.info/2023/11/10/quick-set-up-guide-for-encrypted-client-hello-ech/
And there are live domains with ECH available (https://crypto.cloudflare.com/cdn-cgi/trace), plus Firefox, Chrome and others have it on by default.
I think the easiest starting point will be to expose the OpenSSL functions, then start work on supporting the client-side with urllib and requests (psf/requests#5972). How does that sound?
irl commentedon Jun 2, 2025
As part of the above mentioned Open Tech Fund work, I've got a working branch with support for setting ECH related options, and with the help of dnspython (to fetch the HTTPS/SVCB records) to establish ECH connections (client only). This uses the agreed API with the openssl maintainers and is currently on a feature branch in openssl.
My branch has been based on 3.13 although I'll be updating it this week to be based on main.
https://github.com/irl/cpython/tree/ech is where I am working, but the branch off main will be a new branch.
I have also added some documentation to the bottom of the ssl module's page to describe what ECH is and basic usage:
https://irl.github.io/cpython/library/ssl.html#encrypted-client-hello
That may need updating a little as some of the API names changed since the initial development and the subsequent openssl feature branch.
OSTIF-Derek commentedon Dec 9, 2025
Hello everyone, quick update: The current source for the DEfO ECH project for cpython's SSL module is getting a full security audit through OSTIF.org. Additionally, we will be providing the fuzzing harnesses provided to the DEfO maintainers, with the intention that when the ECH patch gets accepted, it will have corresponding fuzz testing ready to go on ossfuzz for continuous dynamic testing.
Note that this is the CURRENT source and that if any API changes are built after our evaluation, we will need to revisit the project and review the diff to ensure that everything is sound and that we have as much test coverage as we can get for integration.
We have just completed a similar engagement with the DEfO integration of OpenSSL and it has gone well. The public report about this work will be released on our website in early 2026.
sftcd commentedon Sep 14, 2026
Hiya - I've updated the DEfO implementation to 3.15 (so as to match where debian are at for our test harness), but more or less the same changes seemed ok with the upstream latest when I checked that.
What's the best way to try get this ECH clien-side feature upstreamed? It's not very complex (indeed the whole thing is one smallish patch) in the debian build.
I'd be fine with creating a fresh PR for this, or processing it however best, if there's a realistic chance of it being upstreamed in the next while.
Note that the ECH spec is now RFC9849 and the ECH code required for this was part of the OpenSSL v4.0 release back in April this year, so I'd argue it's now mature enough to be upstreamed here.