Add TLS Encrypted Client Hello (ECH) support#1527
Open
gfw-report wants to merge 2 commits intoapernet:masterfrom
Open
Add TLS Encrypted Client Hello (ECH) support#1527gfw-report wants to merge 2 commits intoapernet:masterfrom
gfw-report wants to merge 2 commits intoapernet:masterfrom
Conversation
Example usage: generate ech-keypair outer-sni.com --outConfig ech.config --outKey ech.key
Author
|
The corresponding PR for documentation: apernet/hysteria-website#49 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds support for TLS Encrypted Client Hello (ECH) to both the Hysteria client and server, allowing the true SNI to be encrypted inside the TLS handshake. This makes it harder for passive network observers to determine which server a client is connecting to.
ech.keyFileconfig field and passes the parsed keys to the QUIC/TLS listener.tls.ech.configFileconfig field and sends the encrypted ClientHello accordingly.hysteria generate ech-keypairCLI command generates a matching ECH config (for clients) and key (for the server) in PEM format.Usage
1. Generate an ECH key pair
The
example.comargument is the "public name" (outer SNI) visible to observers instead of the real server name.2. Server configuration
3. Client configuration
With ECH enabled, a passive observer sees the public name generated with the ECH key and config (e.g.
example.com) as the outer SNI, while the actual SNI (real-server.example.com) is encrypted. Note thatserver: real-server.example.com:443can still expose your real domain name via plaintext DNS lookup. One may consider using only an IP address in this case or use encrypted DNS.Files changed
app/internal/utils/ech.goapp/cmd/generate.gogenerateparent commandapp/cmd/generate_ech.gogenerate ech-keypairsubcommandapp/cmd/server.goapp/cmd/client.gocore/server/config.go,core/server/server.gotls.Configcore/client/config.go,core/client/client.gotls.ConfigNote on active probing
A censor could 1) first observe the QUIC connections between a user and a server, and then 2) active probe the server by connecting with the observed outer SNI but a dummy (invalid) ECH payload. If the server fails the TLS handshake (because it cannot present a certificate for the outer SNI domain), the censor can confirm the server is using ECH and thus block by the combination of outer SNI and server IP address.
One possible mitigation may be for the server to relay such requests to the real outer SNI server when ECH decryption fails, rather than returning a TLS error. But this is out of scope for this PR.
That said, to our knowledge no censor other than China's GFW has deployed active probing at scale, and even the GFW has not been observed to actively probe ECH yet as of March 2026. ECH is still valuable for users in countries where censors rely only on passive observation. This limitation should not block the PR.