Skip to content

Latest commit

 

History

History
112 lines (80 loc) · 3.64 KB

File metadata and controls

112 lines (80 loc) · 3.64 KB

Encrypted Client Hello (ECH)

fetch supports Encrypted Client Hello (ECH), a TLS 1.3 extension that encrypts the ClientHello message—including the SNI (Server Name Indication)—so passive network observers cannot see which server the client is connecting to.

Quick Start

# Auto mode: use ECH if the server advertises it
fetch --ech auto https://example.com

# Require ECH (fail if unavailable)
fetch --ech on https://cloudflare.com

# Disable ECH
fetch --ech off https://example.com

Modes

  • auto — Use ECH if the server advertises it in DNS. Falls back to GREASE ECH when an authenticated lookup completes without a real config. An authenticated DNS transport, server, or response failure stops the connection to prevent downgrade. If the server rejects the ECH offer, the connection proceeds (outer ClientHello fallback). This is the recommended mode for general use.

  • on — Require ECH. Errors if the server does not advertise ECH in DNS, and fails if the server rejects the offer. This mode cannot be used with explicit HTTP/3 because fetch cannot verify ECH acceptance on QUIC connections. Automatic protocol selection uses TCP when this mode is active.

  • off — Never use ECH (the default).

    ECH defaults to off rather than auto because auto requires an extra DNS SVCB query on every HTTPS request, which adds latency with no benefit if the server does not support ECH. Use --ech auto or set ech = auto in your config to enable opportunistic ECH.

GREASE ECH

In auto mode, when no real ECH config is found, fetch sends a randomized GREASE ECH extension to prevent protocol ossification. This happens automatically and requires no extra flags.

How It Works

  1. Discovery: fetch queries the server's HTTPS/SVCB DNS record for the ech SvcParam (key 5). This record contains the server's public ECH configuration.

  2. Handshake: fetch encrypts the real ClientHello (with the target SNI) inside an outer ClientHello addressed to a "cover" or "public name". The server that holds the corresponding private key decrypts the inner ClientHello.

  3. DNS privacy: ECH is most effective when paired with verified encrypted DNS (--dns-server with HTTPS DoH, DoT, or DoQ). In -vvv mode, fetch warns once when ECH discovery uses system DNS, UDP, TCP, an HTTPS DoH endpoint with certificate verification disabled, or a plaintext HTTP endpoint in a build that permits one. System DNS is included because fetch cannot verify its transport protection. --silent suppresses this warning.

Configuration

ECH mode can be set in ~/.config/fetch/config:

ech = auto

Or per-host:

[example.com]
ech = on

TLS Version Requirements

ECH requires TLS 1.3. If ECH is active and --min-tls or --max-tls would allow TLS 1.2, fetch reports an error. Remove the version constraints or raise them to 1.3 when using ECH.

Inspection

  • --inspect-dns shows the ECH configuration when a server advertises it in HTTPS/SVCB records (displayed as ECH=<base64>).

  • --inspect-tls reports whether ECH was accepted or rejected by the server, along with the outer/cover SNI.

curl Compatibility

curl's --ech flag maps to fetch:

curl fetch
--ech hard --ech on
--ech true --ech on
--ech auto --ech auto
--ech false --ech off

The --from-curl flag translates curl's ECH flags automatically.

See Also