// Engineering Log

HTTP, HTTPS y TLS: Parte 5 — Versiones de TLS, conjuntos de cifrado, SNI, ALPN, ECH y mTLS

Publicado el 05.10.2026

// Ruta rapida

Este articulo pertenece al tema Seguridad y proteccion.

Bajo la expresión «tipo de TLS» normalmente se entienden cosas distintas: la versión del protocolo (1.2 o 1.3), el conjunto de algoritmos de cifrado, el tipo de certificado (DV, OV, EV) o el esquema en el que también presenta certificado el cliente (mTLS). En esta parte — los cuatro, además de las extensiones ClientHello, de las que depende qué sitio y qué protocolo recibirá el cliente: SNI, ALPN y ECH.

Versiones del protocolo

VersiónAñoEstado
SSL 2.01995prohibida (RFC 6176)
SSL 3.01996prohibida (RFC 7568), ataque POODLE
TLS 1.01999obsoleta (RFC 8996, 2021)
TLS 1.12006obsoleta (RFC 8996, 2021)
TLS 1.22008soportada, requiere configuración correcta
TLS 1.32018actual, recomendada

Los navegadores desactivaron TLS 1.0 y 1.1 en 2020. En el servidor hoy se habilitan TLS 1.2 y 1.3. Dejar solo 1.3 es posible si entre los clientes no hay hardware y software antiguo: Android anteriores a la versión 10, Java 8 sin actualizaciones, versiones antiguas de .NET, clientes integrados de cajas y terminales que solo soportan 1.2.

Conjunto de cifrado

El conjunto de cifrado (cipher suite) es la combinación de algoritmos sobre la que acuerdan cliente y servidor. En TLS 1.2 el nombre describe todo de una vez:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
     │     │        │           └ hash para la derivación de claves
     │     │        └ cifrado de los datos y modo (AEAD)
     │     └ algoritmo de firma del certificado
     └ intercambio de claves

En TLS 1.3 el intercambio de claves y la firma se sacaron a extensiones separadas, y el cipher suite describe solo el cifrado y el hash. Son solo cinco, y todos son seguros:

  • TLS_AES_128_GCM_SHA256;
  • TLS_AES_256_GCM_SHA384;
  • TLS_CHACHA20_POLY1305_SHA256 — más rápido que AES en procesadores sin aceleración por hardware AES, por ejemplo en algunos ARM;
  • TLS_AES_128_CCM_SHA256 y TLS_AES_128_CCM_8_SHA256 — para dispositivos embebidos, no se usan en la web.

Para TLS 1.2 hay que dejar solo los conjuntos con intercambio de claves ECDHE (perfect forward secrecy) y cifrados AEAD — GCM o ChaCha20-Poly1305. Desactivar:

  • intercambio de claves RSA (TLS_RSA_WITH_...) — no hay forward secrecy;
  • cifrados en modo CBC — fuente de ataques como Lucky13;
  • RC4, 3DES, NULL, EXPORT, conjuntos anónimos.

Intercambio de claves y criptografía poscuántica. Los grupos para intercambio de claves — x25519, secp256r1, secp384r1. Desde finales de 2024 Chrome, y luego Firefox y Safari, por defecto ofrecen el grupo híbrido X25519MLKEM768: el clásico X25519 junto con el algoritmo poscuántico ML-KEM. La idea es proteger contra el escenario «grabar ahora, descifrar después», cuando el tráfico se guarda con la esperanza de un ordenador cuántico futuro. OpenSSL lo soporta desde la versión 3.5 (2025). La clave ClientHello con este grupo supera 1 KB y no cabe en un único paquete TCP — algunos cortafuegos y balanceadores antiguos fallan por esto.

Configuración lista para Nginx

No elija cifrados a mano. Mozilla mantiene un generador de configuraciones (ssl-config.mozilla.org) con tres perfiles: modern (solo TLS 1.3), intermediate (TLS 1.2 y 1.3, recomendado para la mayoría de sitios) y old (para compatibilidad con clientes muy antiguos). El perfil intermediate para Nginx se parece a esto:

nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_ciphers actúa solo sobre TLS 1.2: los cipher suites de TLS 1.3 en OpenSSL se configuran por separado, y los valores por defecto son adecuados. ssl_prefer_server_ciphers off deja la elección al cliente — todos los conjuntos dejados son seguros, y el cliente sabe mejor si tiene AES por hardware.

Comprobar el resultado se puede con el servicio SSL Labs (ssllabs.com/ssltest) o localmente — con la utilidad testssl.sh, que funciona también para direcciones internas.

SNI

SNI (Server Name Indication, RFC 6066) — extensión del ClientHello en la que el cliente escribe en texto claro el nombre del sitio. Sin ella, el servidor con varios sitios en una misma IP no sabe qué certificado dar: el handshake va antes de que llegue el encabezado Host.

Qué es importante saber:

  • en Nginx el certificado se elige según server_name de acuerdo con SNI; si no hay SNI o el nombre es desconocido, responde el default_server para ese listen — y el cliente recibe un certificado de otro sitio;

  • para no revelar certificados de otros sitios al consultar por IP, cree un servidor por defecto vacío que interrumpa el handshake:

    nginx
    server {
        listen 443 ssl default_server;
        ssl_reject_handshake on;   # Nginx 1.19.4+
    }
  • SNI es el principal indicio por el que los equipos DPI determinan a qué sitio va el tráfico y lo bloquean;

  • las direcciones IP no se transmiten en SNI: al acceder a https://192.0.2.10/ el campo está vacío.

ALPN

ALPN (Application-Layer Protocol Negotiation, RFC 7301) — extensión en la que el cliente enumera protocolos y el servidor elige uno: h2, http/1.1, h3 para QUIC. Así se acuerda HTTP/2 sin rondas extra de intercambio. ALPN lo usan también otros protocolos sobre TLS: acme-tls/1 para la verificación de dominio de Let’s Encrypt por el método TLS-ALPN-01, dot para DNS-over-TLS.

ECH

SNI y ALPN van en ClientHello en texto claro. La extensión ECH (Encrypted Client Hello, RFC 9849, marzo de 2026) cifra estos campos con una clave que el servidor publica en un registro DNS de tipo HTTPS — el observador ve solo el nombre genérico del proveedor. Cómo está diseñado ECH, dónde funciona y por qué en Rusia las conexiones con él se bloquean se analiza en el artículo «Qué es ECH».

Tipos de certificados: DV, OV, EV

La diferencia es solo quién verificó antes de emitirlo — el cifrado es igual en todos.

  • DV (Domain Validation) — verificado solo el control del dominio: un archivo en el sitio (HTTP-01) o un registro en DNS (DNS-01). Se emite automáticamente en minutos. Let’s Encrypt, ZeroSSL, Google Trust Services emiten solo DV — y es suficiente para cualquier sitio.
  • OV (Organization Validation) — además se verifica la organización. El nombre de la empresa se ve en los detalles del certificado, pero el navegador no lo resalta.
  • EV (Extended Validation) — verificación extendida. Antes los navegadores mostraban el nombre de la empresa en verde en la barra de direcciones; desde 2019 ya no lo hacen. EV ya no da beneficios visibles al usuario.

Separado, por cobertura de nombres: simple, multidominio (varios nombres en SAN) y wildcard (*.example.ru). Wildcard en Let’s Encrypt se emite solo mediante verificación DNS-01.

Certificados rusos. Desde 2022 el Ministerio de Desarrollo Digital emite certificados para sitios rusos desde su propio centro certificador (Russian Trusted Root CA). Esa raíz no está en los almacenes de Chrome, Firefox y Safari; la soportan Yandex Browser y Atom, en otros navegadores y en el SO la raíz debe instalarse manualmente. Además existe TLS con algoritmos rusos GOST — se usa en sistemas estatales y requiere medios criptográficos certificados en ambos extremos.

mTLS: certificado en el cliente

En HTTPS normal solo presenta certificado el servidor. Con autenticación mutua (mutual TLS, mTLS) el servidor solicita también un certificado al cliente y deja pasar solo a quienes tengan un certificado firmado por un CA de confianza. Se usa para acceso a paneles administrativos, comunicación entre microservicios, recepción de webhooks, APIs para socios.

Configuración en Nginx:

nginx
server {
    listen 443 ssl;
    server_name admin.example.ru;

    ssl_certificate     /etc/letsencrypt/live/admin.example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/admin.example.ru/privkey.pem;

    ssl_client_certificate /etc/nginx/client-ca.crt;  # CA que emite certificados de cliente
    ssl_verify_client on;                             # opcional — permitir incluso sin certificado
    ssl_verify_depth 2;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Client-DN $ssl_client_s_dn;
    }
}

Emitir tu propio CA y certificado de cliente:

bash
# CA
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout client-ca.key -out client-ca.crt -days 3650 -subj "/CN=Example Client CA"

# clave y solicitud del cliente
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout ivanov.key -out ivanov.csr -subj "/CN=ivanov"

# firma de la solicitud
openssl x509 -req -in ivanov.csr -CA client-ca.crt -CAkey client-ca.key \
  -CAcreateserial -out ivanov.crt -days 365

Comprobación:

bash
curl https://admin.example.ru/                                   # 400 No required SSL certificate was sent
curl --cert ivanov.crt --key ivanov.key https://admin.example.ru/ # 200

Para el navegador el certificado se empaqueta en PKCS#12: openssl pkcs12 -export -in ivanov.crt -inkey ivanov.key -out ivanov.p12 — y se importa en el sistema.

El CA del cliente no tiene que ser público; al contrario: si indicas en ssl_client_certificate un CA público, pasará cualquiera que le compre un certificado. Para revocar certificados de cliente — ssl_crl. Si delante de Nginx hay un CDN o balanceador que termina TLS, mTLS debe configurarse en ese componente.

Errores típicos

  • TLS 1.0 y 1.1 quedaron habilitados «por compatibilidad» — los escáneres de seguridad y los requisitos PCI DSS lo marcan como vulnerabilidad.
  • En la configuración hay una larga lista de cifrados copiada hace diez años, con CBC e intercambio RSA — usa el generador de Mozilla.
  • No hay un default_server vacío con ssl_reject_handshake — al consultar por la dirección IP, los escáneres obtienen un certificado con todos tus dominios.
  • Un certificado wildcard se copia en decenas de servidores — la compromisión de uno revela todos los subdominios. Mejor certificados separados vía ACME.
  • mTLS con ssl_verify_client optional sin comprobar $ssl_client_verify en la aplicación — un cliente sin certificado pasa.

// 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

Seguridad y proteccion

SSL, hardening, accesos, proteccion de servicios y configuraciones seguras.

Tareas frecuentes de esta tema

  • Configurar SSL, certificados y conexiones seguras
  • Restringir accesos y cerrar puntos de entrada innecesarios
  • Reforzar la configuracion del servidor y los servicios

// 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