Resumen

  • server_name es un nombre DNS que el cliente aporta en ClientHello para orientar una selección temprana de certificado, contexto TLS o destino passthrough; no es una credencial del cliente.
  • La identidad de servicio, Host/:authority, el SNI de salida, las vistas ECH y la autorización de aplicación requieren comprobaciones separadas, aunque sus cadenas coincidan.

El ataque que no necesitó romper TLS

El cliente anónimo anunció el nombre de un tenant valioso. El callback encontró una entrada válida, cambió el contexto TLS y presentó el certificado previsto. Al terminar el handshake, una integración copió la etiqueta de esa entrada al campo principal.

Hasta ahí, TLS había hecho exactamente lo pedido. SNI existe para que un servidor que comparte dirección entre servicios virtuales pueda preparar la configuración apropiada antes de enviar un certificado. El dato proviene del cliente. Por tanto, cualquier cliente puede escoger un nombre permitido por la sintaxis.

El certificado seleccionado ayuda al cliente a autenticar al servidor. No demuestra que el servidor haya autenticado al cliente. El fallo apareció cuando la operación convirtió una elección de configuración en pertenencia al tenant.

La gramática no otorga derechos

RFC 6066 define una lista server_name dentro de ClientHello. El tipo normalizado host_name contiene un nombre DNS en ASCII; no admite direcciones IPv4 ni IPv6 literales, y un mismo tipo no puede repetirse en la lista.

Esas reglas acotan el formato. No acreditan una consulta DNS, control de zona, posesión de una clave, vínculo contractual ni acceso a datos. Es posible conectar a una dirección fijada manualmente y enviar otro nombre. Eso es útil para operación y también trivial para un atacante.

Ante un nombre entendido pero no aceptado, el servidor puede terminar con unrecognized_name. También puede seguir con una política de respaldo. Una revisión debe probar ausencia, nombre desconocido y virtual host por defecto. La frase “SNI está configurado” no revela cuál de esas ramas gobernó la conexión.

Autenticar el transcript no autentica la titularidad

En TLS 1.3, ClientHello integra el transcript protegido finalmente por Finished. Una vez validado, los extremos saben que un intermediario no cambió en secreto el SNI ordinario dentro de ese handshake.

El resultado autentica la integridad de la afirmación, no el derecho a formularla. El servidor sabe que el cliente pidió ese nombre. Sigue sin saber si lo controla o si actúa por la organización que lo opera.

Cuando no existe certificado cliente ni otra autenticación, un handshake correcto mantiene anónimo al solicitante. La autenticación del certificado servidor opera en sentido opuesto: el cliente verifica el servicio.

Por eso la telemetría debe decir client_requested_server_name. Si lo llama verified_domain o tenant_identity, ya ha escrito una conclusión que el protocolo nunca produjo.

Selección y verificación del certificado

El SNI puede llevar al servidor a la credencial más adecuada. Después, el cliente decide si la credencial es aceptable para la identidad de referencia que construyó por su cuenta.

RFC 9525 separa expresamente el identificador de referencia de los identificadores presentados en el certificado. El cliente debe comprobar coincidencia, cadena y política. La selección del servidor no sustituye esas verificaciones.

OpenSSL también separa las operaciones. Configurar SNI con SSL_set_tlsext_host_name() no basta: la aplicación cliente ha de configurar el nombre DNS esperado para validar el certificado. Es posible recibir el certificado deseado y, aun así, no haber autenticado correctamente el servicio.

Un certificado con varios SAN puede cubrir dos nombres legítimos. Esa cobertura no une sus cuentas ni sus permisos. La validez criptográfica es una condición de transporte, no una regla de tenancy.

Host y :authority no son una segunda copia de SNI

Después del handshake llega la petición HTTP. HTTP/1.1 usa Host; HTTP/2 y HTTP/3 suelen transportar :authority. RFC 9110 los trata como información crítica para reconstruir y enrutar el objetivo de la petición.

Un cliente convencional genera ambos nombres desde la misma URI y por eso suelen coincidir. Sin embargo, pertenecen a capas y momentos distintos. Reutilización de conexiones, proxies, pruebas, errores y ataques pueden separarlos.

El servidor necesita una política explícita de divergencia: rechazo, conjunto compartido muy concreto o 421 cuando la conexión no sirve para ese origen. No debe permitir que el SNI inicial autorice silenciosamente todas las autoridades HTTP posteriores.

Tampoco la igualdad autentica al cliente. Solo demuestra coherencia entre dos indicaciones de destino; la aplicación todavía necesita una identidad y una decisión de permiso.

El proxy comienza otro contrato TLS

Al terminar TLS, el proxy cierra una frontera probatoria. Su conexión upstream crea otro ClientHello, otro SNI, otro certificado y otro transcript.

El nombre de salida puede ser fijo, derivarse del host upstream, provenir de la autoridad HTTP o de un mapa. Envoy expone esas alternativas y distingue validar SAN contra el SNI real de salida de validarlo contra el host de la petición. Son decisiones que deben quedar registradas por separado.

En passthrough, el dispositivo puede actuar con todavía menos evidencia. ssl_preread de NGINX extrae SNI y enruta bytes cifrados sin terminar TLS. Puede afirmar que leyó una pista y eligió un backend; no que el certificado fue aceptado ni que el handshake acabó.

Copiar el valor downstream al registro upstream no crea continuidad. Se necesitan dos identidades de conexión y la fuente exacta de cada selección y verificación.

ECH cambia la vista, no elimina la frontera

Encrypted Client Hello guarda los parámetros sensibles en ClientHelloInner. ClientHelloOuter suele incluir el nombre público del servicio frontal para que el tráfico llegue y pueda funcionar el mecanismo de reintento.

Cuando ECH se acepta, el servidor procesa el inner autenticado. Cuando se rechaza, una conexión autenticada para el nombre público solo puede servir al reintento. RFC 9849 indica que no autentica el origen y no debe entregarse a la aplicación como éxito.

Así, el SNI exterior puede ser perfectamente correcto para el enrutamiento y deliberadamente incorrecto como origen. Un campo genérico sni que omite estado ECH y procedencia mezcla dos autoridades incompatibles.

La trazabilidad debe distinguir inner, outer y ClientHello ordinario. A la vez, debe limitar quién recibe el nombre interior: una plataforma de observabilidad que lo replica sin control reconstruye la exposición que ECH pretende reducir.

Las pruebas deben intentar abusar de la pista

Primero, enviar el SNI de un tenant privilegiado sin identidad cliente. La selección del certificado puede pasar; la ruta privilegiada debe quedar cerrada.

Después, omitir SNI, enviar uno desconocido y forzar el fallback. Introducir un Host o :authority de otro tenant y repetir con un certificado válido para ambos nombres. La autorización no puede depender de que la criptografía haga visible el error.

En un proxy, fijar un SNI upstream diferente y verificar dos historiales. En passthrough, impedir etiquetas de certificado validado o handshake terminado. En ECH, recorrer aceptación, rechazo/reintento y ausencia de ECH, siempre identificando la vista usada.

Una API de callback y un archivo de configuración demuestran capacidad. La respuesta del código ejecutado ante estas discrepancias demuestra control.