Fallo en el handshake TLS de SMTP: arregla certificados, cifrados y cadenas correctamente

¿Te fue útil?

Funcionaba ayer. Hoy tu cola de salida parece un vertedero y tus registros de entrada están llenos de “handshake failure” y “unknown CA”. Mientras tanto, un vicepresidente te reenvía capturas de pantalla de una factura rebotada como si hubieras derretido internet personalmente.

SMTP sobre TLS no es “configurar y olvidar”. Es una negociación entre dos sistemas que cambian de forma independiente: los certificados caducan, los almacenes de raíz evolucionan, las preferencias de cifrado cambian y un día uno de los extremos decide que tu servidor vive en 2014. Esta es la guía de campo para arreglarlo sin aplicar configuraciones por copia ritual ni degradar la seguridad hasta que “funcione”.

Guía rápida de diagnóstico

Si estás de guardia, no necesitas una conferencia. Necesitas un bucle cerrado: reproducir, clasificar, arreglar la capa correcta y seguir adelante.

1) Confirma dónde falla: antes de STARTTLS, durante el handshake o después

  • Antes de STARTTLS: STARTTLS no ofrecido, puerto incorrecto, firewall o política que rechaza cifrado (sí, eso existe).
  • Durante el handshake: incompatibilidad de protocolo/cifrado, cadena de certificados mala, certificado equivocado por SNI, certificado caducado o problema en el almacén de confianza del cliente.
  • Después del handshake: falla la autenticación SMTP, la política rechaza o hay problemas a nivel de aplicación mal reportados como TLS.

2) Ejecuta una sonda canónica desde el lado que falla

Haz esto desde el mismo segmento de red y host que experimenta el error. TLS es susceptible a las mentiras de “funciona desde mi portátil”.

Usa openssl s_client con STARTTLS y captura la cadena de certificados además del protocolo y cifrado negociados.

3) Decide en qué cubeta estás

  • “No peer certificate” / “handshake failure” inmediatamente: incompatibilidad de protocolo/cifrado, STARTTLS no se está realizando realmente o el servidor aborta por política/SNI.
  • “verify error:num=20/21 unable to get local issuer certificate”: presentación de cadena rota o intermedio faltante.
  • “certificate has expired” / “not yet valid”: ciclo de vida del certificado o desajuste de reloj.
  • “hostname mismatch”: certificado equivocado, SNI no usado o mal configurado, o el MX apunta a donde no esperabas.

4) Arregla el servidor primero a menos que controles el cliente

En SMTP, a menudo no controlas el extremo remoto. Eso significa: arregla lo que presentas y lo que negocias. Si tu servidor es el que inicia correos salientes (rol cliente), arregla también tu almacén de confianza y políticas, pero no parchees una configuración de servidor rota con “accept_invalid_certs = yes”. Eso no es una solución; es un plan de incumplimiento.

Cómo se rompen realmente los handshakes TLS en SMTP (y por qué los registros mienten)

SMTP TLS tiene dos modos comunes:

  • TLS implícito (SMTPS en 465): TLS comienza inmediatamente después de la conexión TCP.
  • STARTTLS (habitualmente en 25 o 587): el cliente se conecta en texto plano, envía EHLO, ve STARTTLS y luego actualiza la conexión.

Los fallos de handshake suelen informarse con una sola línea deprimente, pero la falla real suele ser una de estas:

  1. Desajuste de negociación: No hay protocolo compartido (TLS 1.0 frente a TLS 1.2+) o no hay suites de cifrado compartidas.
  2. Problemas de cadena de certificados: El servidor presenta un certificado leaf pero olvida los intermedios. Algunos clientes pueden recuperar los intermedios faltantes; muchas pilas SMTP no lo hacen.
  3. Problemas de confianza: El cliente no confía en la cadena (almacén de raíces antiguo, CA privada, raíz ausente o una CA recientemente no confiable).
  4. Problemas de identidad: El certificado no coincide con el nombre que el cliente espera (nombre MX vs nombre del banner vs SNI).
  5. Problemas de política: El servidor exige certificados de cliente, exige SNI, rechaza firmas débiles o aplica expectativas MTA-STS/DANE sobre la otra parte.
  6. Middleboxes: Firewalls “ayudan” interceptando o alterando STARTTLS, o la inspección TLS saliente sale mal.

Una verdad operacional: SMTP es un ecosistema. Puedes ejecutar una configuración perfecta y aun así fallar con un par que está mal configurado. Tu trabajo es mantener tu lado correcto, observable y razonablemente compatible—sin convertirte en el último servidor TLS 1.0 del planeta.

Idea parafraseada, con atribución: “La esperanza no es una estrategia.” — a menudo atribuida en círculos de confiabilidad a Gene Kranz, reflejando pensamiento operativo (parafraseado).

Hechos e historia interesantes para usar

  • STARTTLS fue una vía de actualización, no un diseño desde cero. Existe porque el correo ya estaba por todas partes en texto plano y nadie iba a replatformar el planeta.
  • El puerto 465 tuvo una vida extraña. Comenzó como “SMTPS”, se desalentó en favor de STARTTLS y luego volvió como un puerto de envío TLS reconocido en la práctica moderna.
  • TLS 1.3 cambió la forma del handshake. Menos round trips, nombres de suites de cifrado diferentes y menos palancas heredadas. Genial para seguridad; confuso para scripts de monitorización antiguos.
  • Algunos clientes SMTP no recuperan intermedios faltantes. Los navegadores son indulgentes; los MTAs a menudo no lo son. No asumas que algo se arreglará automáticamente.
  • SNI es más joven que la mayoría de los servidores de correo. Si alojas múltiples dominios en una IP, los clientes modernos envían SNI, pero históricamente no todas las pilas SMTP lo hacían.
  • La deprecación de SHA-1 aún persigue a equipos de larga vida. Equipos antiguos pueden rechazar firmas más nuevas, y equipos nuevos rechazan firmas antiguas. Todos están decepcionados.
  • Los registros CAA pueden romper renovaciones silenciosamente. Si tu automatización renueva vía ACME y CAA bloquea al emisor, lo descubrirás cuando el certificado caduque—en un fin de semana.
  • La seguridad basada en DNS (DANE, MTA-STS) cambió expectativas. Algunos remitentes ahora insisten en TLS válido y verificable para la entrega, y postergarán en lugar de degradar.
  • Los almacenes de confianza son documentos políticos. Una CA puede ser confiable hoy y no confiable mañana. Tu argumento de “es un certificado válido” no servirá si la raíz desaparece.

Tareas prácticas: comandos, salidas, decisiones

Estas son las tareas que realmente ejecuto durante incidentes. Cada una incluye el comando, qué significa la salida y qué decisión tomar a partir de ella.

Task 1: Check that the server offers STARTTLS on port 25

cr0x@server:~$ nc -nv mail.example.net 25
(UNKNOWN) [203.0.113.10] 25 (smtp) open
220 mx1.example.net ESMTP Postfix

Significado: TCP funciona y alcanzaste un banner SMTP. Si esto se cuelga o caduca, aún no estás depurando TLS.

Decisión: Si TCP falla, arregla el enrutamiento/firewall/DNS primero. Si el banner es del host equivocado, sigue los MX y los balanceadores.

Task 2: Confirm STARTTLS is advertised

cr0x@server:~$ printf "EHLO probe.example\r\nQUIT\r\n" | nc -nv mail.example.net 25
(UNKNOWN) [203.0.113.10] 25 (smtp) open
220 mx1.example.net ESMTP Postfix
250-mx1.example.net
250-PIPELINING
250-SIZE 52428800
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
221 2.0.0 Bye

Significado: STARTTLS existe. Si falta, TLS está deshabilitado o la política lo oculta (raro pero real).

Decisión: Si STARTTLS falta en el MX entrante, revisa la configuración del MTA y asegúrate de que el listener TLS esté habilitado.

Task 3: Perform a STARTTLS handshake probe with SNI

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.net:25 -servername mail.example.net -showcerts -verify_return_error
CONNECTED(00000003)
depth=2 C = US, O = Example Root CA, CN = Example Root CA R1
verify return:1
depth=1 C = US, O = Example Issuing CA, CN = Example Issuing CA G2
verify return:1
depth=0 CN = mail.example.net
verify return:1
---
Certificate chain
 0 s:CN = mail.example.net
   i:C = US, O = Example Issuing CA, CN = Example Issuing CA G2
-----BEGIN CERTIFICATE-----
...snip...
-----END CERTIFICATE-----
 1 s:C = US, O = Example Issuing CA, CN = Example Issuing CA G2
   i:C = US, O = Example Root CA, CN = Example Root CA R1
-----BEGIN CERTIFICATE-----
...snip...
-----END CERTIFICATE-----
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Verify return code: 0 (ok)

Significado: Negociaste TLS 1.3 y la validación tuvo éxito. La cadena incluye el intermedio.

Decisión: Si tus clientes de producción aún fallan, compara su almacén de confianza, soporte de protocolos, comportamiento SNI y requisitos de política.

Task 4: Probe without SNI to catch the “default cert” problem

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.net:25 -showcerts -verify_return_error
CONNECTED(00000003)
depth=0 CN = default.invalid
verify error:num=62:Hostname mismatch
80DB5E2E677F0000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:../ssl/statem/statem_clnt.c:1889:
---
Certificate chain
 0 s:CN = default.invalid
   i:C = US, O = Example Issuing CA, CN = Example Issuing CA G2
---
Verify return code: 62 (Hostname mismatch)

Significado: Sin SNI, el servidor entrega un certificado por defecto para otro nombre.

Decisión: Si alojas múltiples nombres, asegúrate de que tu demonio SMTP soporte SNI y tenga el mapeo correcto por nombre; de lo contrario dedica una IP o presenta un certificado que cubra todos los nombres relevantes vía SAN.

Task 5: Identify protocol version mismatch (client too old or server too strict)

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.net:25 -tls1
CONNECTED(00000003)
140735215769152:error:0A000102:SSL routines:ssl_choose_client_version:unsupported protocol:../ssl/statem/statem_lib.c:1950:
no peer certificate available

Significado: El servidor rechaza TLS 1.0. Eso es normal en 2026.

Decisión: Si un cliente heredado no puede usar TLS 1.2+, actualízalo o aíslalo detrás de un relay controlado. No vuelvas a habilitar TLS 1.0 en tu MX público a menos que disfrutes de retrospectivas de incidentes.

Task 6: Identify cipher suite mismatch

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.net:25 -tls1_2 -cipher 'RC4-SHA'
CONNECTED(00000003)
140735215769152:error:0A000410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1605:SSL alert number 40
no peer certificate available

Significado: Ofreciste una suite de cifrado antigua; el servidor la rechazó. Bien.

Decisión: Si sucede al revés (el cliente solo ofrece basura), la solución está en el cliente. Si tu servidor solo ofrece basura, arregla tu biblioteca TLS y la configuración.

Task 7: Verify the certificate chain file on disk

cr0x@server:~$ openssl x509 -in /etc/ssl/mail/mail.example.net.crt -noout -subject -issuer -dates -ext subjectAltName
subject=CN = mail.example.net
issuer=C = US, O = Example Issuing CA, CN = Example Issuing CA G2
notBefore=Dec  1 00:00:00 2025 GMT
notAfter=Mar  1 23:59:59 2026 GMT
X509v3 Subject Alternative Name:
    DNS:mail.example.net, DNS:mx1.example.net

Significado: Las fechas y los SANs parecen sanos. La expiración está próxima: eso ya es un incidente futuro programado.

Decisión: Si SAN no coincide con el hostname al que se conectan tus pares (a menudo el nombre MX), corrige la emisión y alinea el nombrado con DNS.

Task 8: Ensure the presented chain is complete and ordered

cr0x@server:~$ openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt -untrusted /etc/ssl/mail/intermediate.pem /etc/ssl/mail/mail.example.net.crt
/etc/ssl/mail/mail.example.net.crt: OK

Significado: Dado el intermedio, el leaf verifica contra las raíces del sistema.

Decisión: Si esto falla, probablemente tienes el intermedio equivocado, una cadena incompleta o un certificado de una CA privada no confiada por los pares.

Task 9: Inspect what the SMTP service actually presents (not what you think it presents)

cr0x@server:~$ openssl s_client -starttls smtp -connect 203.0.113.10:25 -servername mail.example.net 2>/dev/null | openssl x509 -noout -subject -issuer -ext subjectAltName
subject=CN = mail.example.net
issuer=C = US, O = Example Issuing CA, CN = Example Issuing CA G2
X509v3 Subject Alternative Name:
    DNS:mail.example.net, DNS:mx1.example.net

Significado: Estás comprobando el servicio en vivo, no el archivo en /etc/ssl que nadie cargó realmente.

Decisión: Si la salida en vivo difiere del disco, tienes problemas de recarga, ruta equivocada en la configuración o múltiples MTAs/listeners.

Task 10: Confirm your MTA is listening where you think

cr0x@server:~$ ss -ltnp | egrep ':(25|465|587)\s'
LISTEN 0      100          0.0.0.0:25        0.0.0.0:*    users:(("master",pid=1243,fd=13))
LISTEN 0      100          0.0.0.0:587       0.0.0.0:*    users:(("master",pid=1243,fd=14))
LISTEN 0      100          0.0.0.0:465       0.0.0.0:*    users:(("master",pid=1243,fd=15))

Significado: El master de Postfix está enlazado a los tres puertos. Si 465 no aparece, SMTPS no está habilitado.

Decisión: Haz coincidir la realidad de los listeners con tus ajustes publicados y las expectativas de los clientes.

Task 11: Pull the exact TLS errors from Postfix logs

cr0x@server:~$ sudo grep -E "warning: TLS|SSL_accept|SSL_connect|handshake" /var/log/mail.log | tail -n 8
Jan 03 11:04:18 mx1 postfix/smtpd[22418]: warning: TLS library problem: error:0A000076:SSL routines::no suitable signature algorithm:../ssl/t1_lib.c:3364:
Jan 03 11:04:18 mx1 postfix/smtpd[22418]: lost connection after STARTTLS from unknown[198.51.100.23]
Jan 03 11:06:44 mx1 postfix/smtpd[22502]: warning: TLS library problem: error:0A000410:SSL routines::sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1605:SSL alert number 40
Jan 03 11:06:44 mx1 postfix/smtpd[22502]: lost connection after STARTTLS from mail.partner.example[203.0.113.77]

Significado: “No suitable signature algorithm” suele apuntar a desajustes RSA/EC o limitaciones de pares muy antiguos.

Decisión: Decide si vas a soportar la pila TLS de ese socio. Si es una dependencia comercial importante, enrútalo vía un relay dedicado con compatibilidad ajustada; no debilites el MX principal.

Task 12: Check the outbound side: what your server negotiates when acting as a client

cr0x@server:~$ openssl s_client -starttls smtp -connect mx.partner.example:25 -servername mx.partner.example -brief
CONNECTION ESTABLISHED
Protocol version: TLSv1.2
Ciphersuite: ECDHE-RSA-AES256-GCM-SHA384
Peer certificate: CN = mx.partner.example
Hash used: SHA256
Signature type: RSA-PSS
Verification: OK

Significado: La negociación saliente del cliente tuvo éxito; el protocolo/cifrado parecen suficientemente modernos.

Decisión: Si la salida falla solo desde tu MTA pero funciona con OpenSSL, revisa la política TLS del MTA, el soporte SNI y las rutas de archivos CA.

Task 13: Validate system clock and time sync (yes, it matters)

cr0x@server:~$ timedatectl
Local time: Sat 2026-01-03 11:12:29 UTC
Universal time: Sat 2026-01-03 11:12:29 UTC
RTC time: Sat 2026-01-03 11:12:29
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

Significado: La hora está sincronizada. Si no lo está, los errores “not yet valid” en certificados son caos garantizado.

Decisión: Arregla NTP antes de tocar configuraciones TLS. Un reloj equivocado hace que cualquier certificado parezca culpable.

Task 14: Confirm the CA store your MTA uses is populated

cr0x@server:~$ ls -l /etc/ssl/certs/ca-certificates.crt
-rw-r--r-- 1 root root 214392 Jan  2 02:14 /etc/ssl/certs/ca-certificates.crt

Significado: Tienes un bundle consolidado de CA. Algunos MTAs están configurados para usar bundles personalizados; verifica que existan y estén actualizados.

Decisión: Si usas un archivo CA personalizado, documéntalo y automatiza actualizaciones. Si no, mantenlo en la ruta estándar del SO.

Broma 1: Un fallo de handshake TLS es como dos ejecutivos reuniéndose: ambos insisten en que son compatibles y ninguno cambiará sus valores por defecto.

Cadenas de certificados: cómo construirlas correctamente

El fallo número uno de TLS en SMTP que veo en producción: servidores que presentan una cadena incompleta. Los navegadores a menudo reparan esto recuperando intermedios mediante Authority Information Access (AIA). Los clientes SMTP generalmente no lo harán. Dan por hecho lo que les diste y se van.

Qué significa “cadena correcta” en términos SMTP

  • Certificado leaf: para el hostname SMTP al que se conectan los pares (típicamente el nombre MX).
  • Certificado(s) intermedio(s): necesarios para enlazar el leaf a una raíz presente en el almacén de confianza del cliente.
  • Certificado raíz: normalmente no enviado por el servidor; los clientes ya lo tienen. Enviarlo suele ser inofensivo pero puede confundir a pilas rotas y hace el troubleshooting más ruidoso.

El orden importa

Cuando concatenes certificados, hazlo en el orden: leaf primero, luego cada intermedio subiendo en la cadena. No incluyas la raíz salvo que tengas una razón específica. Si obtuviste un “fullchain.pem” de tu CA, normalmente contiene leaf + intermedios, que es lo que quieres presentar.

Cómo aparecen los problemas de cadena en registros reales

  • Error del lado cliente: “unable to get local issuer certificate” o “unknown ca”.
  • Sintoma del lado servidor: la conexión se corta justo después de STARTTLS, a menudo registrada como “lost connection after STARTTLS”.
  • Olor operacional: algunos receptores aceptan correo y otros lo posponen por horas, dependiendo de su pila TLS y de la frescura del almacén de confianza.

No mezcles archivos de cadena por servicio a la ligera

Un host puede servir HTTPS, IMAPS, POP3S y SMTP. Cada servicio puede configurarse para usar una ruta de archivo de certificado diferente. Si “renovaste el certificado” pero solo actualizaste el servidor web, felicidades: arreglaste el servicio equivocado. Esto ocurre más de lo que cualquiera admite.

Cifrados y versiones de protocolo: deja de negociar como en 1999

Cuando el handshake falla con “no shared cipher” o “protocol version”, estás viendo una de dos situaciones:

  1. Tu servidor es demasiado estricto para un par legítimo que debes soportar.
  2. El par es obsoleto y no deberías degradar tu seguridad base.

Parte de opinión: para un MX expuesto a internet, da preferencia a TLS 1.2 y TLS 1.3, cifrados AEAD modernos y curvas razonables. Si alguien no puede hablar con eso, puede entregar sin TLS si tu política lo permite, o puede actualizar. Tu trabajo es entrega de correo y gestión de riesgo, no mantener un museo de compatibilidad.

Realidad SMTP: no controlas a la mayoría de los pares

Pero puedes controlar cómo fallas:

  • Para entrada: puedes ofrecer TLS pero seguir aceptando texto plano si tu política lo permite. Eso mantiene el flujo de correo sin imponer seguridad.
  • Para salida: puedes exigir TLS a dominios específicos (mapas de política) o aplicar MTA-STS/DANE cuando esté disponible.

Trampa de optimización: “Deshabilitamos TLS 1.2 porque 1.3 es más rápido”

TLS 1.3 es excelente. Aun así necesitas TLS 1.2 para compatibilidad con una parte de la infraestructura SMTP que no ha actualizado, incluidos algunos appliances gestionados. Mantén TLS 1.2 habilitado salvo que tengas un entorno controlado y excepciones documentadas.

SNI, verificación de nombres y la trampa del “certificado equivocado”

SNI (Server Name Indication) es cómo un cliente le dice al servidor qué hostname quiere durante el handshake TLS. Sin SNI, el servidor elige un certificado por defecto. Eso está bien para servidores de un solo dominio. Es un desastre para gateways de correo multiinquilino.

De dónde viene el nombre esperado

Los clientes SMTP normalmente se conectan al hostname MX que obtuvieron desde DNS. Validan el certificado contra ese nombre. Si tu registro MX apunta a mx1.example.net pero tu certificado solo contiene mail.example.net, te creaste tu propio corte de servicio. Alinea el nombrado primero; no intentes “configurar alrededor” de la verdad DNS.

Tres planos de nombres que debes alinear

  • DNS: el MX apunta a un hostname; A/AAAA lo mapea a IPs.
  • Banner SMTP: lo que tu servidor dice en el saludo 220. No se usa directamente para la validación TLS, pero afecta al debugging y señales de reputación.
  • SANs del certificado: los nombres para los que el certificado es válido. Esto es lo que importa para las comprobaciones de nombre TLS.

Si alojas múltiples dominios en un mismo MX, aún puedes usar un único certificado que cubra múltiples hostnames vía SANs, o usar selección basada en SNI si tu MTA lo soporta correctamente. La elección “correcta” depende de la complejidad operativa: la proliferación de SANs es fea, pero una mala configuración de SNI es más fea.

Patrones de configuración de MTA (Postfix, Exim) que envejecen bien

Seré práctico: quieres configuraciones explícitas, testeables y recargables sin sorpresas.

Postfix: esenciales de TLS entrante

  • Usa un archivo de cadena completa para smtpd_tls_cert_file (leaf + intermedios).
  • Apunta smtpd_tls_key_file a la llave privada correspondiente.
  • Establece un nivel mínimo de protocolo que refleje tu postura de riesgo; típicamente TLS 1.2.
  • Registra lo suficiente para depurar (smtpd_tls_loglevel), pero no tanto que causes un DDoS en tus propios discos.

Postfix: esenciales de TLS saliente

En salida es donde la política se vuelve real. Puedes hacer TLS oportunista por defecto y exigir TLS por dominio cuando sea necesario.

  • Oportunista: intenta STARTTLS cuando se ofrezca, pero entrega sin él si el par no lo soporta.
  • Exigido por dominio: requiere TLS para partners específicos y falla cerrado cuando no esté disponible.

Exim: misma física, diferentes controles

Exim también te permite dispararte en el pie con la configuración TLS. El principio guía es el mismo: presenta una cadena completa, asegura la coincidencia de nombres, mantén versiones de protocolo modernas y prueba tanto con SNI como sin SNI cuando sea relevante.

Tres mini-historias corporativas desde el terreno

1) El outage causado por una suposición equivocada

La empresa tenía un único gateway de correo que manejaba entrada para múltiples marcas. El DNS estaba limpio, los registros MX apuntaban a mx.brand-a.example y mx.brand-b.example, ambos resolviendo a la misma IP. El equipo renovó certificados mediante un cliente ACME y todo “parecía bien” desde una comprobación de navegador.

El lunes por la mañana, un subconjunto de partners empezó a posponer correo a la marca B. Los registros mostraban “TLS handshake failed” en el lado del remitente, mientras que el receptor veía “lost connection after STARTTLS” sin errores de certificado obvios. El ingeniero de guardia hizo lo que muchos hacen bajo presión: activó más logging y lo miró más detenidamente. Nada.

La suposición equivocada fue sutil: creían que todos los clientes SMTP envían SNI como lo hacen los clientes web modernos. Muchos lo hacían. Algunos no. Esos clientes recibían el certificado por defecto—el de la marca A—porque el demonio de correo seleccionaba el primer certificado configurado en ausencia de SNI.

La solución no fue suplicar a los partners que actualicen. La solución fue dejar de depender de SNI para la corrección. Emitieron un certificado con SANs que cubrían ambos hostnames MX y configuraron el servicio SMTP para presentar ese único certificado. También actualizaron la monitorización para probar con y sin SNI, porque la realidad tiene esquinas.

Después, el equipo documentó la regla que ya debería haber existido: para SMTP público, SNI es una característica de rendimiento/organización, no una dependencia de corrección—a menos que hayas validado explícitamente tu ecosistema de pares.

2) La optimización que salió mal

Otra organización se enorgullecía de endurecer la seguridad. Deshabilitaron TLS 1.2 en su servicio de submission porque “TLS 1.3 es más seguro y más rápido.” Esto se desplegó junto con un nuevo balanceador y un bonito informe de cumplimiento. Todos durmieron tranquilos.

Dos semanas después, recibieron una ola de quejas de usuarios: clientes móviles que no podían enviar correo intermitentemente. No todos los clientes. No todas las redes. Por supuesto. El helpdesk culpó a las contraseñas y forzó restablecimientos, lo que empeoró el problema y enfureció a los usuarios.

La causa raíz fue compatibilidad: varios clientes móviles gestionados todavía negociaban solo TLS 1.2. Esos clientes no eran “malos”, eran “lentos para actualizar”, que es básicamente el estado por defecto de la gestión de endpoints corporativos. Los logs del balanceador mostraban fallos de handshake; los logs de la aplicación estaban mayormente silenciosos.

La solución fue reactivar TLS 1.2 en submission y seguir prefiriendo TLS 1.3. Además, movieron el proceso de “cambio de postura de seguridad” para incluir un canario de compatibilidad: antes de deshabilitar una versión de protocolo, medirían quién todavía la usa en el borde de submission.

Lección: mejoras de seguridad que rompen el correo no son mejoras de seguridad; son ataques a la productividad que te auto-lanzas.

3) La práctica aburrida pero correcta que salvó el día

Un proveedor SaaS mediano ejecutaba sus relays de correo en dos centros de datos. Nada exótico. Hicieron dos cosas religiosamente: mantener el inventario de certificados en la gestión de configuración y ejecutar sondas sintéticas diarias que validaban handshakes TLS tal como lo hacen peers SMTP reales.

Un día una CA rotó un intermedio de forma perfectamente legítima. Su cliente ACME renovó el leaf, pero la pipeline de despliegue accidentalmente subió solo el leaf a los relays de uno de los centros de datos—sin el intermedio. La mitad de sus entregas salientes empezaron a ser pospuestas por receptores más estrictos. La otra mitad siguió fluyendo porque el otro centro de datos estaba configurado correctamente.

Por qué no se convirtió en un “incidente mayor”: su sondeo sintético lo detectó en minutos porque probaba openssl s_client -starttls smtp -showcerts y verificaba la longitud de la cadena y el estado de verificación. La alerta no decía “cola de correo alta.” Decía “cadena TLS incompleta en mx2.” Específico, accionable, aburrido.

La reversión fue inmediata. Sin heroísmos. Sin arqueología en Slack. Solo un redeploy limpio con el archivo de cadena completa correcto y un postmortem centrado en por qué la pipeline permitió ese artefacto de cadena parcial.

La corrección aburrida está subestimada hasta que es lo único que te separa de una semana de “el correo es poco fiable” y daño reputacional.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: “STARTTLS not offered”

  • Causa raíz: TLS deshabilitado en el MTA, servicio equivocado (submission vs MX) o un proxy/balanceador que elimina extensiones.
  • Solución: Confirma con una sonda raw EHLO. Habilita STARTTLS en el listener correcto. Si hay un proxy enfrente, asegúrate de que pase SMTP de forma transparente o termine TLS correctamente.

2) Síntoma: “lost connection after STARTTLS” en tus logs

  • Causa raíz: el par abortó el handshake por cadena no confiable, mismatch de hostname o incompatibilidad de protocolo/cifrado.
  • Solución: Ejecuta openssl s_client -starttls smtp -servername ... -showcerts desde el lado del par si es posible; de lo contrario reproduce desde un host externo. Valida la completitud de la cadena y el protocolo negociado.

3) Síntoma: “verify error:num=20 unable to get local issuer certificate”

  • Causa raíz: faltan intermedios en lo que el servidor presenta.
  • Solución: configura el servicio para presentar la cadena completa (leaf + intermedios). No asumas que los clientes recuperarán AIA.

4) Síntoma: “certificate has expired” pero lo renovaste

  • Causa raíz: el servicio sigue usando el archivo antiguo, no se realizó reload, se actualizó el listener equivocado o un balanceador termina TLS con su propio cert.
  • Solución: consulta el certificado en vivo y compara su serial/fechas con el disco. Recarga el demonio correcto. Actualiza el almacén de certs del balanceador si termina TLS.

5) Síntoma: “wrong version number” en OpenSSL

  • Causa raíz: te conectaste con TLS implícito a un puerto STARTTLS (o viceversa), o un servicio no-TLS está en ese puerto.
  • Solución: usa -starttls smtp para puertos 25/587 y openssl s_client -connect host:465 para 465.

6) Síntoma: funciona desde algunos remitentes, falla desde otros

  • Causa raíz: dependencia de SNI, diferencias en presentación de cadena entre nodos o pares con distintos almacenes de confianza/soporte de protocolos.
  • Solución: prueba con y sin SNI; prueba cada nodo/IP del MX; asegura despliegue consistente de la cadena en la flota.

7) Síntoma: fallo de handshake solo después de una actualización de la librería cripto

  • Causa raíz: valores por defecto más estrictos (tamaño mínimo de clave, algoritmos de firma, cifrados heredados deshabilitados).
  • Solución: inspecciona la firma/cipher negociados, ajusta la política de forma intencional y documenta excepciones. No vuelvas a habilitar algoritmos obsoletos globalmente a ciegas.

Broma 2: Si todavía habilitas TLS 1.0 “por ese único partner”, básicamente estás adoptando un tigre doméstico porque parecía solo.

Listas de verificación / plan paso a paso

Checklist de incidente: restablecer el correo sin crear un incidente de seguridad

  1. Reproduce desde el punto de vista que falla. Mismo host/red si es posible.
  2. Identifica el modo: STARTTLS (25/587) vs TLS implícito (465).
  3. Captura evidencia del handshake: protocolo, cifrado, cadena presentada, código de verificación.
  4. Valida el nombrado: qué hostname usan los pares (MX) y si está en SAN.
  5. Valida la completitud de la cadena: leaf + intermedios presentados y ordenados correctamente.
  6. Revisa expiración y sincronización horaria: fechas de certificados, reloj del sistema, estado NTP.
  7. Comprueba comportamiento SNI: compara la sonda con y sin -servername.
  8. Verifica consistencia en la flota: prueba cada IP del MX directamente, no solo el hostname.
  9. Solo entonces ajusta la política TLS: protocolos/cifrados mínimos, excepciones por par si son críticas para el negocio.
  10. Despliega con seguridad: recarga servicios, confirma certificado en vivo y vuelve a ejecutar sondas.
  11. Cierra el ciclo: vacía colas, vigila posposiciones y confirma aceptación por parte de partners.
  12. Escribe la nota posmortem: qué falló, qué detección falló, qué automatizarás.

Checklist de endurecimiento: mantener compatibilidad sin ser imprudente

  • Habilita TLS 1.2 y TLS 1.3; deshabilita TLS 1.0/1.1 en servicios expuestos a internet salvo que tengas una excepción limitada y documentada.
  • Prefiere cifrados AEAD; evita intercambio de clave RSA estático.
  • Usa un certificado con SANs que coincidan con los hostnames MX. No relies en comportamiento solo-CN.
  • Presenta una cadena completa (leaf + intermedios). Prueba con un verificador estricto.
  • Automatiza renovaciones y recargas, y verifica la presentación en vivo tras el despliegue.
  • Monitorea desde fuera de tu red con sondas STARTTLS, no solo comprobaciones HTTPS.
  • Documenta dónde se termina TLS (MTA vs balanceador). Un único punto de terminación por flujo es una característica de cordura.

Plan de gestión de cambios: hacer cambios TLS sin sorpresas

  1. Recolecta telemetría: versiones de protocolo negociadas y cifrados actuales (en submission y, si es posible, en inbound).
  2. Escala cambios en un nodo primero (canario MX), mide posposiciones y errores de handshake.
  3. Comunica cambios que afecten a partners antes de exigir TLS.
  4. Despliega a la flota con validación automatizada: sondea cada nodo/IP y verifica cadena y coincidencia de nombres.
  5. Mantén una ruta de rollback de emergencia que no implique habilitar protocolos obsoletos globalmente.

FAQ

1) ¿Por qué OpenSSL verifica OK pero Postfix (o un partner) aún falla?

Diferentes almacenes de confianza, diferentes valores por defecto y a veces diferente comportamiento SNI. OpenSSL puede usar el bundle CA del SO; tu MTA puede usar un archivo CA personalizado o mapas de política más estrictos.

2) ¿Debo incluir la CA raíz en la cadena que presento?

Normalmente no. Presenta leaf + intermedios. Las raíces pertenecen a los almacenes de confianza de los clientes. Incluir la raíz rara vez ayuda y a veces confunde a clientes rotos.

3) ¿Cuál es el error más común en la cadena?

Desplegar solo el certificado leaf. Los clientes SMTP a menudo no recuperan intermedios, así que la verificación falla aunque “el certificado sea válido” en un navegador.

4) ¿Puedo arreglar fallos de handshake permitiendo cifrados más débiles?

A veces, pero a menudo es la decisión equivocada. Si un par solo soporta cifrados débiles, enruta ese tráfico a través de un relay controlado con una política acotada. No debilites tu MX principal para internet.

5) ¿Por qué algunos remitentes posponen en lugar de entregar sin TLS?

Algunos remitentes aplican políticas TLS (requisitos por dominio, MTA-STS, DANE o cumplimiento interno). Prefieren retrasar antes que arriesgar entrega en texto plano.

6) ¿Qué suele significar “no suitable signature algorithm”?

La negociación del algoritmo de firma falló—a menudo porque el par es muy antiguo o por el tipo de certificado/clave (RSA-PSS/ECDSA) que no puede validar. La solución es una política de compatibilidad o actualizar el par, no cambios aleatorios de cifrados.

7) ¿El puerto 465 es “incorrecto” para SMTP?

No. El puerto 465 se usa comúnmente para submission con TLS implícito. Para transporte servidor-a-servidor, el puerto 25 con STARTTLS sigue siendo la norma. Usa el modo correcto para la audiencia correcta.

8) ¿Cómo sé si SNI es el problema?

Prueba con y sin -servername. Si el certificado cambia, tienes selección basada en SNI. Decide si puedes depender de ello o emite un certificado que cubra todos los nombres necesarios.

9) Si mi certificado cubre el hostname equivocado—¿puedo simplemente cambiar el registro MX?

Puedes, pero hazlo deliberadamente. Los nombres MX son parte de tu identidad de correo y huella de reputación. A menudo la solución más segura es reemitir el certificado para coincidir con el MX existente y alinear DNS, banner y SANs.

Conclusión: siguientes pasos que sobreviven auditorías

Los fallos de handshake TLS en SMTP rara vez son “aleatorios”. Suelen ser deterministas: nombre equivocado, cadena incompleta, protocolo/cifrado incompatible o despliegue inconsistente entre nodos. La salida es dejar de adivinar y empezar a interrogar el servicio en vivo con sondas estrictas.

Haz lo siguiente:

  1. Ejecuta una sonda STARTTLS con -showcerts y captura protocolo/cifrado negociado y código de verificación.
  2. Repite sin SNI y directamente contra cada IP del MX para exponer certificados por defecto y deriva.
  3. Arregla la presentación de la cadena (leaf + intermedios) y asegúrate de que los SANs coincidan con los hostnames MX.
  4. Mantén TLS 1.2 + 1.3 habilitados; evita degradaciones globales para un único peer legado—usa relays acotados o políticas por destino.
  5. Automatiza la validación: tras cada renovación y cada cambio relacionado con TLS, verifica qué presenta el servicio en la red.

Si haces una sola cosa diferente después de leer esto: deja de confiar en el archivo de certificado en disco. Confía en lo que la red ve.

← Anterior
Debian 13: SSHFS vs NFS — elige el que no se bloquee al azar (y configúralo bien)
Siguiente →
IPC > GHz: la explicación más simple que realmente recordarás

Deja un comentario