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

Support TLS Encrypted ClientHello (ECH) #89730

Open
eighthave mannequin opened this issue Oct 22, 2021 · 4 comments
Open

Support TLS Encrypted ClientHello (ECH) #89730

eighthave mannequin opened this issue Oct 22, 2021 · 4 comments
Assignees
Labels
topic-SSL type-feature A feature request or enhancement

Comments

@eighthave
Copy link
Mannequin

eighthave mannequin commented Oct 22, 2021

BPO 45567
Nosy @tiran, @eighthave

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/tiran'
closed_at = None
created_at = <Date 2021-10-22.08:59:46.592>
labels = ['expert-SSL', 'type-feature']
title = 'Support TLS Encrypted ClientHello (ECH)'
updated_at = <Date 2021-11-02.15:51:37.975>
user = 'https://github.com/eighthave'

bugs.python.org fields:

activity = <Date 2021-11-02.15:51:37.975>
actor = 'eighthave'
assignee = 'christian.heimes'
closed = False
closed_date = None
closer = None
components = ['SSL']
creation = <Date 2021-10-22.08:59:46.592>
creator = 'eighthave'
dependencies = []
files = []
hgrepos = []
issue_num = 45567
keywords = []
message_count = 3.0
messages = ['404732', '404749', '405513']
nosy_count = 2.0
nosy_names = ['christian.heimes', 'eighthave']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue45567'
versions = []

@eighthave
Copy link
Mannequin Author

eighthave mannequin commented 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:

  1. HTTPS/SVCB DNS queries for setting up TLS connection with ECH.
  2. A way to provide ECH Config Lists as bytes directly to ssl clients.
  3. A callback that gets called whenever ECH negotiation fails and the server offers a "Retry Config".
  4. 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 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] square/okhttp#6539
[8] https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.html
[9] https://github.com/sftcd/openssl

@eighthave eighthave mannequin assigned tiran Oct 22, 2021
@eighthave eighthave mannequin added topic-SSL type-feature A feature request or enhancement labels Oct 22, 2021
@eighthave eighthave mannequin assigned tiran Oct 22, 2021
@eighthave eighthave mannequin added topic-SSL type-feature A feature request or enhancement labels Oct 22, 2021
@tiran
Copy link
Member

tiran commented 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
Copy link
Mannequin Author

eighthave mannequin commented 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
Copy link

eighthave commented 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?

@mishase mishase mentioned this issue May 5, 2024
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-SSL type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants