Encrypted client hello ech represents the definitive solution to the Server Name Indication (SNI) privacy leak within the Transport Layer Security (TLS) protocol stack. While TLS 1.3 successfully encrypted the majority of the handshake, the SNI field remained in plaintext; this allowed network intermediaries, service providers, and malicious actors to monitor the destination hostname of every outgoing connection. By integrating as an extension to TLS 1.3, encrypted client hello ech provides a mechanism where the client encrypts the entire ClientHello message under a public key published by the server via the Domain Name System (DNS). In large-scale cloud and network infrastructures, this protocol is essential for maintaining metadata privacy and preventing bypass of censorship or traffic filtering. The transition from legacy SNI to ECH shifts the architectural burden from simple cleartext routing to a sophisticated Hybrid Public Key Encryption (HPKE) model. This manual details the configuration, deployment, and optimization of ECH within high-concurrency environments where privacy and performance are non-negotiable requirements.
Technical Specifications
| Requirement | Default Port/Operating Range | Protocol/Standard | Impact Level (1-10) | Recommended Resources |
| :— | :— | :— | :— | :— |
| TLS Library | N/A (Internal) | TLS 1.3 / RFC 9446 | 10 | OpenSSL 3.x+ / BoringSSL |
| DNS Resolver | Port 53 / 853 / 443 | HTTPS/SVCB RR (Type 64) | 9 | 16GB RAM / DoH Support |
| CPU Overhead | User Space | HPKE (X25519/AES-GCM) | 4 | +15% per Core |
| Network Throughput | 1 Gbps to 100 Gbps | TCP/443 | 2 | Low Jitter / Low Packet-loss |
| Storage (Logs) | /var/log/audit | POSIX Filestream | 6 | NVMe / High IOPS |
The Configuration Protocol
Environment Prerequisites:
Successful deployment requires a Linux-based kernel (version 5.15 or higher) to support advanced socket options and efficient context switching. All administrative actions must be performed by a user with sudo privileges or equivalent CAP_NET_ADMIN capabilities. The infrastructure must utilize a TLS library that explicitly supports HPKE and ECH; standard OpenSSL 1.1.1 is insufficient. Currently, BoringSSL or specifically patched versions of OpenSSL 3.2+ are required. Furthermore, the authoritative DNS server must support the HTTPS Resource Record (RR) type 64, which is the primary delivery vehicle for the ECHConfig payload.
Section A: Implementation Logic:
The engineering design of encrypted client hello ech relies on a dual-message structure: the ClientHelloOuter and the ClientHelloInner. The ClientHelloOuter is a cleartext message containing a non-sensitive public_name (e.g., a generic provider domain). The ClientHelloInner contains the actual sensitive request, including the intended SNI and extensions. This inner message is encrypted using HPKE, ensuring that even if a network observer captures the packet, they only see the generic public_name. This design is idempotent; repeatedly performing the handshake with the same keys results in the same encrypted outcome without side effects on server state until the session is established. This encapsulation strategy significantly reduces the surface area for traffic analysis while managing the payload overhead efficiently to avoid fragmentation across the MTU (Maximum Transmission Unit) boundary.
Step-By-Step Execution
1. Generate HPKE Key Pair
The first step involves generating the cryptographic material used to encrypt the ClientHelloInner. Use the following command structure to generate a private key and its corresponding public ECHConfig via a compatible utility:
openssl ech -genkey -out ech_private.key -pubout ech_public.config
System Note: This command generates a X25519 key pair. The private key remains on the edge server; whereas, the public config is formatted for distribution via DNS. This action interacts with the kernel entropy source to ensure high-quality randomness for the key material.
2. Configure DNS SVCB/HTTPS Records
The public key and associated metadata must be published to your DNS zone file. The record typically looks like this:
example.com. 3600 IN HTTPS 1 . ech=”[Base64-encoded-ech_public.config]”
System Note: The DNS server processes this as a Type 64 record. When a client performs a lookup, it retrieves the ECHConfig before initiating the TLS handshake. High latency in DNS resolution will directly impact the time-to-first-byte (TTFB) for the TLS connection.
3. Build Web Server with ECH Support
Since most mainstream distributions do not ship with ECH enabled by default in Nginx or HAProxy, you must compile from source using a compliant library.
./configure –with-openssl=/path/to/ech-enabled-openssl –with-http_ssl_module
make && sudo make install
System Note: This process links the higher-level application logic with the low-level crypto primitives. The binary will now be able to intercept the `ClientHelloOuter`, decrypt the `ClientHelloInner` using the local private key, and route the request to the appropriate virtual host.
4. Update Server Configuration
Modify your web server configuration (e.g., /etc/nginx/nginx.conf) to point to the ECH private key.
ssl_ech_key /etc/ssl/private/ech_private.key;
ssl_protocols TLSv1.3;
System Note: The systemctl restart nginx command triggers a configuration reload. The service reads the key into protected memory segments, ensuring that subsequent concurrency is handled by workers with the key already resident in cache.
5. Verify Encapsulation via Packet Analysis
Use a tool like tshark or tcpdump to verify that the SNI is no longer visible in the clear.
tcpdump -i eth0 -w handshake.pcap port 443
System Note: By inspecting the resulting capture in a protocol analyzer, you should observe the encrypted_client_hello extension within the TLS handshake. If the SNI of the backend service is absent, the implementation is successful.
Section B: Dependency Fault-Lines:
The most common point of failure involves a mismatch between the ECHConfig published in DNS and the private key residing on the server. Because DNS records are cached (subject to TTL), rotating a key on the server without allowing the DNS record to propagate will result in handshake failures. Furthermore, if the network path experiences significant packet-loss, the larger TLS handshake packets required by ECH might trigger Path MTU Discovery (PMTUD) issues. If signal-attenuation occurs in wireless segments, the increased size of the initial handshake packet can lead to higher retransmission rates, negatively impacting throughput.
THE TROUBLESHOOTING MATRIX
Section C: Logs & Debugging:
When a connection fails, the first point of inspection should be the server-side error logs, typically located at /var/log/nginx/error.log or /var/log/haproxy.log. Look for specific TLS alert codes. An `SSL_R_ECH_REQUIRED` error indicates the client attempted a legacy handshake on a port where ECH is strictly enforced. Conversely, an `SSL_R_DECRYPTION_FAILED` error suggests the server could not decrypt the ClientHelloInner, likely due to a stale private key.
For deep-drive debugging, use the following environmental variable to increase OpenSSL verbosity:
export OPENSSL_DEBUG_LEVEL=3
Run your client application and watch for output related to extension 0xfe0d (the ECH extension). Ensure the public_name in the configuration matches the certificate presented by the server during the outer handshake: mismatch here will cause browsers to terminate the connection for security reasons.
OPTIMIZATION & HARDENING
– Performance Tuning: To mitigate the latency introduced by the additional decryption step, ensure that your CPU supports hardware acceleration for AES-GCM and X25519. Enable TLS session resumption and 0-RTT (Zero Round-Trip Time) to offset the initial handshake overhead. Monitor the thermal-inertia of your hardware during peak concurrency; the increased cryptographic load can lead to thermal throttling if the cooling infrastructure is insufficient for high-density compute.
– Security Hardening: Restrict the permissions on your private keys using chmod 600 /etc/ssl/private/ech_private.key. Implement strict firewall rules using iptables or nftables to only allow incoming traffic on port 443 from verified network segments if the service is internal. Always ensure the public_name points to a server that does not reveal sensitive client patterns.
– Scaling Logic: In a load-balanced environment, all edge nodes must share the same ECH private key if they are behind a single DNS record. Use an idempotent configuration management tool like Ansible or SaltStack to synchronize these keys across the fleet. As traffic scales, monitor for packet-loss at the load balancer; ECH packets are larger and may hit buffer limits earlier than standard TLS packets.
THE ADMIN DESK
How do I confirm ECH is working in the browser?
Open the browser developer tools and navigate to the security tab. If encrypted client hello ech is active, the connection details will indicate the use of the ECH extension. Alternatively, use a specialized testing site like Cloudflare’s ECH check.
Does ECH work with TLS 1.2?
No. The architecture of ECH is fundamentally designed for the handshake flow of TLS 1.3. It relies on the way extensions are handled in the newer protocol; therefore, attempting to backport it to TLS 1.2 is not feasible.
What is the “public_name” used for?
The public_name serves as a fallback SNI. If the server cannot decrypt the inner hello, it uses the outer hello’s public_name to complete a basic handshake, usually to provide the client with the updated ECHConfig for a subsequent attempt.
Can ECH be blocked by corporate firewalls?
Yes. Firewalls that perform TLS inspection (MITM) will often block ECH because they cannot see the destination SNI. To prevent this, corporate environments usually distribute a custom root certificate and disable ECH via group policy or local configuration.


