Encrypted Client Hello Comes to NGINX

by

in

Encrypted Client Hello (ECH) support in NGINX open source was contributed by Stephen Farrell, Computer Science Research Fellow, Trinity College Dublin (GitHub PR #840). This work was funded by the Open Technology Fund as part of the DEfO (Developing ECH for OpenSSL) project, which develops privacy-enhancing ECH implementations for OpenSSL and various web servers to help protect user privacy and combat censorship.

NGINX 1.29.4 arrives with a feature that privacy advocates and enterprise security teams have been waiting years for: native support for Encrypted Client Hello (ECH). This TLS 1.3 extension represents the final piece in a decade-long effort to encrypt web communications end-to-end, closing the last significant metadata gap that allowed network observers to see which websites users were visiting.

Across this release, we’re focused on:

  • Encrypting the TLS handshake to protect user privacy from network surveillance
  • Providing a standards-based alternative to workarounds like VPNs and domain fronting
  • Positioning NGINX among the first open source proxies with production ECH support
  • Laying groundwork for organizations hosting privacy-sensitive services

Together with the upcoming OpenSSL 4.0 release (expected spring 2026), these updates give platform teams, security engineers, and privacy-focused organizations a practical path to stronger user protection without exotic infrastructure requirements.

The Privacy Gap ECH Closes

Even with HTTPS everywhere, network observers have been able to see which specific websites you visit. The Server Name Indication (SNI) field in the TLS handshake has always been transmitted in plaintext, allowing ISPs, corporate network administrators, and state-level surveillance systems to build detailed profiles of browsing habits.

ECH encrypts this handshake information. When a browser connects to an ECH-enabled server, observers see only a generic “cover” domain (the ECH public_name). The actual destination remains encrypted and is revealed only after the secure connection is established.

Why it matters: This closes the last major metadata leak in encrypted web traffic. Combined with encrypted DNS (DoH/DoT) and ubiquitous HTTPS, ECH completes the privacy picture. For enterprises, metadata leakage represents both a compliance gap and a reconnaissance opportunity for attackers.

Who it helps:

  • Healthcare organizations protecting patient privacy under HIPAA. The 18 HIPAA identifiers include Web URLs and IP addresses, and HHS guidance on tracking technologies has raised questions about metadata exposure. While courts are still determining the full scope of metadata protection requirements, organizations handling sensitive health services benefit from reducing unnecessary exposure
  • Financial institutions subject to GLBA and SOX requirements, where traffic analysis could reveal M&A activity, trading strategies, or client relationships before public disclosure
  • Legal and professional services firms where client confidentiality obligations extend to concealing which matters are being worked on, not just the content of those matters
  • Government contractors meeting NIST 800-53 and CMMC requirements. NIST 800-53 Rev 5 includes controls for metadata protection and transmission confidentiality (SC-8), and organizations increasingly interpret these requirements to include handshake metadata

Shared-Mode Architecture

NGINX 1.29.4 supports ECH “shared-mode” where a single NGINX instance handles both the ECH decryption and hosts both the ECH public_name and backend websites. The configuration involves three key elements: a public-facing domain that serves as the visible “cover” during the encrypted handshake, the actual destination that remains hidden from network observers, and ECH keys published in DNS via HTTPS resource records.

ECH “split-mode,” where NGINX would only perform ECH decryption but pass the TLS session to a different backend service, requires changes to OpenSSL that have yet to be merged to the ECH feature branch. A separate proof-of-concept implementation exists in the defo-project for organizations that need this capability.

Why it matters: Shared-mode architecture allows organizations to deploy ECH without additional infrastructure. A single NGINX instance can protect multiple backend services behind a common public-facing domain, reducing the attack surface visible to external reconnaissance.

Who it helps:

  • Organizations undergoing security audits who need to demonstrate metadata protection controls without deploying additional point solutions
  • Enterprise security teams implementing defense-in-depth strategies where reducing attacker reconnaissance is a documented control
  • Platform teams consolidating ingress infrastructure while maintaining strict service isolation for compliance boundaries

ECH Key Generation and DNS Publication

Using ECH requires generating an ECH key pair and publishing the public component in DNS. The OpenSSL ECH feature branch provides the tooling:

$ openssl ech -public_name example.com -out example.com.pem.ech

This produces a PEM file containing both the private key (for NGINX to decrypt incoming ECH connections) and the ECHConfig (for DNS publication). The ECHConfig value must be published in an HTTPS resource record so browsers can discover it:

$ dig +short HTTPS foo.example.com
1 . ech=AD7+DQA6QwAgACA8mxkEsSTp2xXC/RUFCC6CZMMgdM4x1i
TWKu3EONjbMAAEAAEAAQALZXhhbXBsZS5vcmcAAA==

Why it matters: The DNS-based key distribution model means ECH works with existing browser implementations without requiring client-side configuration. Firefox 118 introduced ECH support, enabled by default in Firefox 119, and Chrome 117 shipped with ECH support.

Who it helps:

  • Security architects designing systems that work with unmodified client browsers
  • Operations teams who can leverage existing DNS infrastructure for key distribution
  • Organizations with key rotation requirements who can publish new keys via DNS without client coordination

Simple Configuration

Enabling ECH requires minimal configuration changes. One or more ssl_ech_file directives point to ECH PEM files. These can be configured in the http or stream blocks, as well as nested server blocks. In nested server blocks, they should appear in the default server. The first configured ECH PEM file is used as the server’s ECH retry configuration.

http {
    ssl_ech_file /etc/echkeydir/example.com.pem.ech;

    server {
        listen 443 ssl;
        server_name example.com;
        # Public-facing "cover" domain matching the ECH public_name
        ssl_certificate /etc/certs/example.com.crt;
        ssl_certificate_key /etc/certs/example.com.priv;

        location / {
            root /var/www/dir-example.com;
            index index.html index.htm;
        }
    }

    server {
        listen 443 ssl;
        server_name foo.example.com;
        # Protected backend service
        ssl_certificate /etc/certs/foo.example.com.crt;
        ssl_certificate_key /etc/certs/foo.example.com.priv;

        location / {
            root /var/www/dir-foo.example.com;
            index index.html index.htm;
        }
    }
}

For ECH retry configuration to work, the NGINX config file must include a virtual server that matches the ECH public_name. The ssl_ech_file directive also works with the Stream module in the same manner.

Why it matters: Teams don’t need to rearchitect their infrastructure or adopt third-party privacy services. ECH integrates directly into existing NGINX deployments, which simplifies change management and reduces the compliance documentation burden of introducing new components.

Who it helps:

  • Operations teams adding privacy controls without introducing new vendors or tools that require separate security assessments
  • Compliance officers who can document ECH as an enhancement to existing approved infrastructure rather than a net-new system requiring full risk assessment
  • Organizations with strict change control processes where modifying existing NGINX configurations is far simpler than deploying additional privacy infrastructure

Operational Visibility

NGINX provides logging variables to monitor ECH status. The $ssl_ech_status variable indicates ECH processing results: SUCCESS, NOT_TRIED, FAILED, BACKEND, or GREASE. The $ssl_ech_outer_server_name variable shows the public-facing domain from the outer SNI when ECH was accepted.

http {
    log_format ech '$remote_addr - [$time_local] "$request" $status '
        'ECH:$ssl_ech_status:$ssl_ech_outer_server_name $ssl_server_name';

    access_log logs/access.log ech;
}

This produces log entries showing ECH status for each connection:

127.0.0.1 - [16/Dec/2025:17:18:49 +0400] "GET / HTTP/1.1" 200 ECH:NOT_TRIED:- foo.example.com
127.0.0.1 - [16/Dec/2025:17:15:57 +0400] "GET / HTTP/1.0" 200 ECH:SUCCESS:example.com foo.example.com

When a client supplies a bad ECH configuration, the server sends an ECH retry configuration back. This terminates the TLS connection after the handshake without creating an HTTP request, so no access log entry appears. Instead, the NGINX error log shows TLS alert 121 (“ECH required”):

2025/12/16 17:23:02 [info] 384291#0: *4 SSL_do_handshake() failed (SSL: error:0A000461:SSL routines::reason(1121):SSL alert number 121) while SSL handshaking, client: 127.0.0.1, server: 0.0.0.0:8443

Note: In version 1.29.5, the log level for this message changed from crit to info, reflecting that this is expected protocol behavior rather than a critical error.

The client then repeats the connection with the correct ECH configuration.

Why it matters: Audit trails are essential for demonstrating control effectiveness. ECH logging provides the evidence that privacy controls are functioning, which auditors and regulators increasingly expect for sensitive workloads.

Who it helps:

  • Security teams preparing for SOC 2, ISO 27001, or FedRAMP audits where control effectiveness must be demonstrated with evidence
  • Compliance analysts who need to show that metadata protection isn’t just configured but actively functioning in production
  • Incident response teams investigating potential data exposure who need to verify whether ECH was active during the relevant timeframe

Reducing Attack Surface Reconnaissance

Beyond compliance, ECH provides concrete security value by limiting what attackers can learn about your infrastructure through passive observation. Traditional TLS exposes which specific services exist behind your ingress points. An attacker conducting reconnaissance can map your internal service landscape simply by observing SNI values in handshake traffic.

With ECH, all services behind a shared NGINX instance appear as connections to a single generic domain. Attackers lose visibility into your service topology, the relative traffic volumes to different services, and patterns that might indicate high-value targets.

Why it matters: Reconnaissance is the first phase of most targeted attacks. Limiting the information available to attackers during this phase raises the cost and complexity of targeting your organization specifically.

Who it helps:

  • Organizations facing advanced persistent threats where attackers invest significant effort in pre-attack reconnaissance
  • Companies in competitive industries where traffic analysis could reveal strategic initiatives, vendor relationships, or internal tooling choices
  • Enterprises with significant brand value who are frequent targets of opportunistic attackers looking for high-profile victims

NGINX’s Position in the ECH Landscape

On September 27, 2024, Cloudflare announced ECH availability for  services on Cloudflare’s infrastructure. For organizations running their own web, proxy, load balancing, API gateway, and content cache infrastructure, NGINX is among the first open-source options with production ECH support.

HAProxy has an open feature request since November 2022 but no production implementation. Traefik has a similar request with significant community interest but no implementation. Apache httpd has a pending pull request from the same team (the DEfO project) that contributed to NGINX’s implementation. The key constraint has been OpenSSL itself, which won’t include ECH in a stable release until version 4.0.

Why it matters: For organizations that can’t route traffic through third-party infrastructure due to data residency, sovereignty, or contractual requirements, NGINX offers the only practical path to ECH today.

Who it helps:

  • Organizations with data sovereignty requirements that prohibit routing traffic through US-based CDN providers
  • Regulated industries where contractual obligations require full control of the traffic path
  • Government and defense contractors where approved product lists don’t include CDN-based solutions

Current Requirements and Limitations

ECH is not yet part of an OpenSSL release. The current goal is for ECH to be part of OpenSSL 4.0 in spring 2026. Until then, ECH-enabling NGINX requires building from source using the OpenSSL ECH feature branch.

Build requirements:

$ git clone https://github.com/openssl/openssl.git openssl-for-nginx
$ cd openssl-for-nginx
$ git checkout feature/ech

$ git clone https://github.com/nginx/nginx.git
$ cd nginx
$ auto/configure --with-openssl=/path/to/openssl-for-nginx \
    --with-debug --prefix=nginx --with-http_ssl_module
$ make

This produces an NGINX binary with a statically linked OpenSSL, avoiding any disturbance to system libraries.

Current limitations:

  • Build from source required: Until OpenSSL 4.0 ships, ECH requires the OpenSSL ECH feature branch
  • Shared-mode only: Split-mode requires additional OpenSSL changes not yet merged; see the defo-project for experimental support
  • DNS configuration required: Browsers discover ECH keys via HTTPS resource records in DNS

Why it matters: Organizations should begin evaluating ECH now to understand the operational requirements and compliance benefits before mainstream availability in 2026.

Who it helps:

  • Security architects planning multi-year roadmaps who need to understand emerging privacy controls
  • Compliance teams evaluating how ECH fits into their control frameworks before auditors start asking about it
  • Early adopters with the engineering capacity to run experimental configurations in non-production environments

Testing Without DNS

ECH can be tested locally without publishing ECH configuration in DNS. Using curl with ECH support:

$ curl --ech ecl:AD7+DQA6EwAgACCJDbbP6N6GbNTQT6v9cwGtT8YUgGCpqLqiNnDnsTIAIAAEAAEAAQALZXhhbXBsZS5jb20AAA== \
    https://foo.example.com --cacert cadir/oe.csr
Or using the OpenSSL s_client tool from the ECH feature branch:
$ echo -e "GET / HTTP/1.0\nHost: foo.example.com\n\n" | \
    openssl s_client -ech_config_list AD7+DQA6EwAgACCJDbbP6N6GbNTQT6v9cwGtT8YUgGCpqLqiNnDnsTIAIAAEAAEAAQALZXhhbXBsZS5jb20AAA== \
    -connect foo.example.com:443 -CAfile cadir/oe.csr -ign_eof

The ECH configuration value comes from the previously generated PEM file.

Wrapping Up

NGINX 1.29.4’s ECH support represents a significant step forward for enterprise privacy and security posture. While the feature currently requires building from source with experimental OpenSSL code, it positions NGINX at the forefront of privacy-enhancing web infrastructure.

For enterprises, ECH addresses a gap that compliance frameworks are increasingly recognizing: metadata protection. The EU has explicitly recognized that metadata derived from electronic communications can reveal sensitive personal information, and US regulators are beginning to examine similar questions. Organizations that implement ECH early will be ahead of the compliance curve rather than scrambling to catch up.

The financial case is straightforward: metadata exposure creates liability, and ECH reduces that exposure. Whether the concern is regulatory fines, breach notification costs, or the reputational damage of a privacy incident, ECH provides a standards-based control that demonstrably reduces risk.

As OpenSSL 4.0 approaches its spring 2026 release, expect ECH deployment to become significantly simpler. Organizations that invest in understanding ECH now will be well-positioned to deploy it broadly once it reaches mainstream availability.

Resources: