direct.ech.jelle.devnot offered (no ECH extension)passthrough (original CH forwarded)TLS (HTTP/2)direct.ech.jelle.devnot offered| Domain | (h2 + h3) | :444 (h2 only) | Mode |
|---|---|---|---|
| proxied-a | visit | visit | split-mode ECH |
| proxied-b | visit | visit | split-mode ECH |
| direct | visit | visit | passthrough ECH |
| noech | visit | visit | no ECH (GREASE) |
| public | visit | visit | outer SNI endpoint |
= TCP + UDP (browser upgrades to h3 via alt-svc) | :444 = TCP only (no QUIC)
All traffic enters through an ECH split-mode proxy on port :443 (TCP+UDP) and :444 (TCP). The proxy peeks at the TLS/QUIC ClientHello, attempts ECH decryption, and routes by SNI:
AcceptedInnerDirect.Accepted).Ignored).Backend servers support HTTP/2 (via ALPN) and advertise alt-svc: h3 on :443 so browsers upgrade to QUIC/HTTP3. The :444 backends do not advertise alt-svc.
The proxy communicates metadata to backends via PROXY protocol v2 (TLS) or a metadata UDP datagram (QUIC), shown in the blue “Proxy metadata” box above.
All components are built with rustls (TLS 1.3 + ECH), quinn (QUIC), and hickory-dns (DNS + DoH). Source: rustls-server-ech-demo.
Served by our own authoritative DNS + DoH server. Browsers query these via DoH to discover ECH configs and ALPN protocols.
ech.jelle.dev. 60 IN A 165.232.148.125 ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, _444._https.ech.jelle.dev. 60 IN HTTPS 1 ech.jelle.dev. alpn=h2,http/1.1, direct.ech.jelle.dev. 60 IN A 165.232.148.125 direct.ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 direct.ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] _444._https.direct.ech.jelle.dev. 60 IN HTTPS 1 direct.ech.jelle.dev. alpn=h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] noech.ech.jelle.dev. 60 IN A 165.232.148.125 noech.ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 noech.ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, _444._https.noech.ech.jelle.dev. 60 IN HTTPS 1 noech.ech.jelle.dev. alpn=h2,http/1.1, proxied-a.ech.jelle.dev. 60 IN A 165.232.148.125 proxied-a.ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 proxied-a.ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] _444._https.proxied-a.ech.jelle.dev. 60 IN HTTPS 1 proxied-a.ech.jelle.dev. alpn=h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] proxied-b.ech.jelle.dev. 60 IN A 165.232.148.125 proxied-b.ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 proxied-b.ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] _444._https.proxied-b.ech.jelle.dev. 60 IN HTTPS 1 proxied-b.ech.jelle.dev. alpn=h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] public.ech.jelle.dev. 60 IN A 165.232.148.125 public.ech.jelle.dev. 60 IN AAAA 2604:a880:4:1d0:0:2:4b59:1000 public.ech.jelle.dev. 60 IN HTTPS 1 . alpn=h3,h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64] _444._https.public.ech.jelle.dev. 60 IN HTTPS 1 public.ech.jelle.dev. alpn=h2,http/1.1, ech=[version=0xfe0d config_id=1 kem=X25519 public_name=public.ech.jelle.dev max_name_len=64]
Port-prefix records (_444._https.*) use the bare domain as TargetName (required for Chrome compatibility).