// Engineering Log

HTTP, HTTPS y TLS: Parte 6 — ¿Qué es ECH (Encrypted Client Hello) y cómo oculta el nombre del sitio?

Publicado el 07.10.2026

// Ruta rapida

Este articulo pertenece al tema Servidores e infraestructura.

ECH (Encrypted Client Hello) — una extensión de TLS 1.3 que cifra el primer mensaje del handshake, ClientHello. Lo principal que oculta es el nombre del sitio en el campo SNI. Sin ECH cualquier nodo entre tú y el servidor ve que abriste shop.example.ru, incluso si todo lo demás está cifrado. Con ECH el observador ve solo un nombre general, idéntico para muchos sitios en un mismo servidor o CDN. El estándar se publicó en marzo de 2026 como RFC 9849, y la forma de publicar las claves en DNS — como RFC 9848.

Qué queda abierto sin ECH

El handshake de TLS 1.3 cifra casi todo, incluido el certificado del servidor. Pero el ClientHello lo envía el cliente antes de que las partes acuerden claves, por eso va en texto claro y contiene:

  • SNI — nombre del sitio;
  • ALPN — lista de protocolos (h2, http/1.1), por la que se puede conocer el tipo de aplicación;
  • conjunto de cifrados, grupos y extensiones, por el que se construyen huellas del cliente (JA3, JA4).

Justo por SNI funcionan los bloqueos de sitios en equipos DPI, los filtros de redes corporativas y el control parental de los proveedores. Antes hubo un intento de cifrar solo el SNI (ESNI, 2018), pero dejaba abiertos los demás campos y no llegó a ser estándar. ECH es su reemplazo: se cifra todo el ClientHello completo.

Cómo funciona

Dos ClientHello en uno. El cliente forma:

  • interno ClientHello — el real, con el nombre del sitio deseado y la lista completa de ALPN;
  • externo ClientHello — público, con un nombre común (public_name), por ejemplo cloudflare-ech.com. El interno está contenido dentro del externo cifrado en la extensión encrypted_client_hello.

El ClientHello externo lo ven todos; el interno solo lo puede leer el servidor que tiene la clave privada ECH.

De dónde saca el cliente la clave. El servidor publica la configuración ECH (ECHConfigList: clave pública, algoritmos y public_name) en un registro DNS de tipo HTTPS para su dominio:

bash
dig +short HTTPS example.ru
1 . alpn="h3,h2" ipv4hint=192.0.2.10 ech=AEX+DQBBpQAgACB...

El navegador solicita ese registro junto con A/AAAA y, si contiene el parámetro ech, cifra el ClientHello. El cifrado es por el esquema HPKE (RFC 9180): el cliente deriva una clave efímera a partir de la clave pública del servidor.

Qué hace el servidor. Descifra el ClientHello interno y continúa el handshake con él, como si no hubiera habido uno externo. En la respuesta al cliente el servidor confirma de forma imperceptible para el observador que ECH fue aceptado.

Si la clave está obsoleta. Las claves ECH se renuevan periódicamente. Si el cliente cifró el ClientHello con una clave antigua, el servidor no podrá descifrarlo y completará el handshake usando el ClientHello externo — con un certificado para public_name — y entregará al cliente la configuración actual (retry configs). El cliente se reconecta con la nueva clave. Por eso el servidor necesita también un certificado válido para el nombre común.

Dos esquemas de despliegue:

  • shared mode — un mismo servidor descifra ECH y sirve los sitios; así funciona Cloudflare y así se soporta ECH en Nginx;
  • split mode — un front separado solo descifra el ClientHello y pasa la conexión al servidor del sitio, sin ver el contenido. Sirve cuando el front y los sitios pertenecen a distintos propietarios.

GREASE ECH. Los navegadores con soporte ECH envían la extensión encrypted_client_hello con datos aleatorios incluso a sitios que no tienen ECH. Esto evita que por la presencia de la extensión se distinga una conexión con ECH real de una conexión normal, y evita que el equipo intermedio aprenda a fallar ante una extensión desconocida.

Qué oculta ECH y qué no

ECH oculta el nombre del sitio a un observador pasivo, pero solo bajo varias condiciones:

  • El DNS también está cifrado. Si la consulta example.ru HTTPS se hizo por DNS normal, el nombre es visible allí. ECH tiene sentido junto con DNS-over-HTTPS o DNS-over-TLS. Firefox utiliza ECH solo cuando DoH está activado.
  • Detrás de la IP hay muchos sitios. Si en la dirección IP hay un solo sitio, el nombre se revela por la propia IP. Por eso ECH funciona de verdad en CDN y grandes hostings, donde bajo una misma IP hay miles de dominios.
  • Apariencia de la conexión. La longitud de la respuesta, el tiempo, la presencia de la extensión — todo eso sigue siendo accesible para análisis de tráfico.

ECH no oculta la dirección IP del servidor y no es un método para eludir bloqueos: se puede bloquear el hecho mismo de usar ECH o toda la dirección del proveedor.

Dónde funciona ECH hoy

  • Navegadores: Chrome desde la versión 117 y Firefox desde la 119 (2023) usan ECH por defecto si encuentran la configuración en DNS.
  • Cloudflare activó ECH para sitios en planes gratuitos en 2023, lo deshabilitó por problemas y volvió a desplegarlo en septiembre de 2024. Su public_name es cloudflare-ech.com.
  • OpenSSL soporta ECH desde la versión 4.0 (abril de 2026). Antes ECH estaba solo en una rama separada de OpenSSL, en BoringSSL (Chrome) y NSS (Firefox).
  • Nginx recibió ECH en la versión 1.29.4 (directiva ssl_ech_file, modo shared mode), cuando se compila con una OpenSSL que soporte ECH.
  • curl — la opción --ech desde la versión 8.8.0 como función experimental, cuando se compila con una biblioteca TLS que soporte ECH.

ECH en Rusia

5–6 de noviembre de 2024 TSPU empezaron a bloquear conexiones con Cloudflare que contienen la extensión ECH — junto con el public_name cloudflare-ech.com. Roskomnadzor explicó que el uso de ECH viola la legislación rusa y recomendó a los propietarios de sitios no usar el CDN Cloudflare. En la práctica, a usuarios con ECH activado les dejaron de abrir muchos sitios en Cloudflare sin relación con política.

Para el propietario de un sitio con audiencia en Rusia se deriva:

  • si el sitio está detrás de Cloudflare y parte de los visitantes se quejan de inaccesibilidad, comprueba si ECH está activado en la sección SSL/TLS → Edge Certificates (en el plan gratuito el interruptor no siempre está disponible — entonces vía API o soporte);
  • activar ECH en el propio servidor para audiencia rusa no tiene sentido: no hay beneficio en ocultar el nombre y sí existe riesgo de bloqueo de la conexión.

Cómo activar ECH en Nginx

Se necesitan Nginx 1.29.4 o superior y OpenSSL 4.0 o superior. Aún hay pocos paquetes listos, por eso normalmente se compila Nginx desde fuentes con la opción --with-openssl=<ruta a las fuentes de OpenSSL 4>.

1. Generar la clave ECH. El archivo contiene la clave privada y la configuración para publicar en DNS:

bash
openssl ech -public_name ech.example.ru -out /etc/nginx/ech/ech.example.ru.pem.ech

public_name — el nombre común que verá el observador. Para él se necesita un certificado normal: se usa cuando el cliente llega con una clave antigua.

2. Conectar la clave. Es conveniente poner la directiva a nivel http, así aplica a todos los sitios:

nginx
http {
    ssl_ech_file /etc/nginx/ech/ech.example.ru.pem.ech;

    log_format ech '$remote_addr "$request" $status '
                   'ech=$ssl_ech_status outer=$ssl_ech_outer_server_name sni=$ssl_server_name';

    server {
        listen 443 ssl;
        server_name ech.example.ru;
        ssl_certificate     /etc/letsencrypt/live/ech.example.ru/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ech.example.ru/privkey.pem;
        return 404;
    }

    server {
        listen 443 ssl;
        server_name shop.example.ru;
        ssl_certificate     /etc/letsencrypt/live/shop.example.ru/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/shop.example.ru/privkey.pem;
        access_log /var/log/nginx/shop.access.log ech;
        root /var/www/shop;
    }
}

La variable $ssl_ech_status toma los valores SUCCESS (ECH aceptado), NOT_TRIED (el cliente no lo intentó), GREASE (el cliente envió un valor de relleno), FAILED y BACKEND.

3. Publicar la configuración en DNS. La cadena en Base64 del archivo .pem.ech (el bloque ECHCONFIG) añádela en un registro HTTPS de cada sitio:

shop.example.ru.  300  IN  HTTPS  1 . alpn="h2,http/1.1" ech="AEX+DQBBpQAgACB..."

No todos los proveedores DNS permiten crear registros de tipo HTTPS; los que no lo permiten — ECH no funcionará.

4. Cambiar las claves. La clave ECH conviene actualizarla cada pocas semanas: generar una nueva, añadirla en Nginx junto a la antigua (la directiva se puede repetir), publicarla en DNS, esperar el TTL, quitar la antigua.

Cómo comprobar

En el navegador. La página https://crypto.cloudflare.com/cdn-cgi/trace muestra la cadena sni=encrypted si ECH funcionó, y sni=plaintext si no. En tu propio sitio el resultado se ve en los logs mediante la variable $ssl_ech_status.

Con curl (se requiere compilación con ECH):

bash
curl --ech true https://shop.example.ru/     # intentar ECH, si no, sin él
curl --ech hard https://shop.example.ru/     # solo ECH, si no — error
curl --ech ecl:AEX+DQBBpQAgACB... https://shop.example.ru/   # configuración manual, sin DNS
curl --ech false https://shop.example.ru/    # no usar ECH

curl obtiene la configuración del registro HTTPS vía DoH, por eso junto con --ech suele especificarse --doh-url https://dns.example.net/dns-query.

Con openssl (4.0 o superior):

bash
openssl s_client -connect shop.example.ru:443 -servername shop.example.ru \
  -ech_config_list AEX+DQBBpQAgACB...

Desde la red. En Wireshark, en una conexión con ECH la SNI será el public_name, y en el ClientHello estará la extensión encrypted_client_hello (tipo 0xfe0d) con un gran bloque de datos.

Errores típicos

  • ECH activado, pero el DNS del cliente es normal — el nombre del sitio sigue siendo visible en la consulta DNS.
  • No hay certificado para public_name — los clientes con clave antigua no pueden obtener uno nuevo y se desconectan.
  • Se cambió la clave en el servidor, pero no se actualizó en DNS, o viceversa — los clientes obtienen error hasta que vence el TTL.
  • ECH activado en un servidor separado con un solo sitio: el nombre no aparece en la SNI, pero se determina inequívocamente por la IP.
  • ECH activado para un sitio con audiencia en Rusia — parte de los visitantes pierde acceso por el bloqueo.

// Tarea parecida

Si estas resolviendo algo parecido

Este articulo pertenece a uno de los temas principales de trabajo. Puedes seguir leyendo sobre el tema, ir a la pagina principal para entender a que me dedico o abrir directamente los servicios.

Tema del articulo

Servidores e infraestructura

VPS, Linux, stack web, migraciones, hosting, bases de datos y operacion base.

Tareas frecuentes de esta tema

  • Migrar un sitio o servicio a un nuevo servidor
  • Configurar Linux, Nginx, base de datos y copias de seguridad
  • Entender por que el sistema funciona de forma inestable

// Siguiente paso

Si necesitas ayuda con este tema y no solo otro articulo, es mejor ir directo a la pagina del servicio. La pagina principal y la seleccion de materiales quedan como rutas secundarias.

Abrir servicios

// Reviews

Reseñas relacionadas

apande

apande

Configuración de Nginx y OpenCart

07.09.2024 · ★ 5/5

Un comprador muy poderoso
kireevk

kireevk

Diagnóstico de Nginx Proxy Manager en un contenedor Docker y solución del problema

15.03.2024 · ★ 5/5

Comprador acostumbrado

// Contact

¿Necesitas ayuda?

Escríbeme y te ayudaré a resolver el problema

Respondo en un día laborable (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirme que no es un bot.

Escribir y recibir una respuesta rápida