
Alguien te dice que tu sitio no es seguro. Lo abres: candado, sin advertencia, certificado válido por otros cuatro meses. Le pides que lo intente de nuevo y sigue fallando, en una red a la que no puedes acceder, en un cliente que no tienes.
Ninguno de ustedes está equivocado, y el certificado no es el problema. Lo que difiere es todo lo que hay debajo.
Un certificado no es de confianza por sí solo
Tu certificado no afirma que sea confiable. Está firmado por un certificado intermedio, que está firmado por una raíz, y solo la raíz está en el almacén de confianza del visitante. El trabajo al conectarse es construir ese camino, y el trabajo de tu servidor es entregar la mitad del mismo.
TLS 1.3 dice qué envía el servidor, y la redacción merece la pena leerla:
certificate_list: Una secuencia (cadena) de estructuras CertificateEntry, cada una conteniendo un único certificado y un conjunto de extensiones.
Y luego la regla que generalmente se omite:
El certificado del remitente DEBE venir en el primer CertificateEntry en la lista. Cada certificado siguiente DEBERÍA certificar directamente el que lo precede inmediatamente. Debido a que la validación de certificados requiere que los anclajes de confianza se distribuyan independientemente, un certificado que especifica un anclaje de confianza PUEDE ser omitido de la cadena, siempre que se sepa que los pares compatibles poseen cualquier certificado omitido.
Lee la última oración con cuidado. El anclaje de confianza, que significa la raíz, puede ser omitido, porque los clientes ya lo tienen. Nada allí justifica omitir el certificado intermedio. Se supone que tu servidor debe enviar todo lo que hay entre tu certificado y la raíz, y un certificado intermedio es precisamente eso.
La configuración errónea que nunca verás tú mismo
Omitir el certificado intermedio no produce un sitio medio roto. Produce un sitio que funciona perfectamente para ti y falla para otras personas, lo que es un resultado considerablemente más costoso.
Mozilla ha descrito no especificar certificados CA intermedios adecuados como “uno de los problemas de configuración de servidor más comunes”, e hizo algo al respecto: Firefox precarga certificados CA intermedios de antemano, en una lista que “contiene más de dos mil entradas”, específicamente para reducir “errores de emisores desconocidos en el TLS Handshake”.
Piensa en lo que eso significa. Los navegadores compensan activamente este error. Un navegador que ya tiene el certificado intermedio completará la conexión sin importar si tu servidor lo envió o no, por lo que tu propia prueba pasa y la configuración errónea permanece invisible. La compensación es una buena ingeniería y también es la razón por la que nadie se da cuenta.
Por qué un cliente falla donde otro tiene éxito
Hay un segundo mecanismo que lo oculta, y proviene del certificado mismo.
Un certificado puede indicar dónde se puede encontrar el certificado de su emisor. RFC 5280 define ese campo, y es cuidadoso acerca de para qué sirve:
El OID id-ad-caIssuers se utiliza cuando la información adicional enumera certificados que fueron emitidos a la CA que emitió el certificado que contiene esta extensión. La descripción de emisores CA referenciada está destinada a ayudar a los usuarios de certificados en la selección de una ruta de certificación
“Destinado a ayudar” es la frase operativa. Es un puntero, no una obligación. Un cliente puede seguirlo y obtener la pieza faltante, y un cliente puede rechazarlo. Ambos son conformes.
La especificación TLS es igualmente franco sobre el estado del mundo, señalando que los servidores a veces envían certificados adicionales o desordenados y que “otros simplemente están configurados incorrectamente”, antes de pedir a las implementaciones que sean tolerantes con ello.
- Lo que probaste
- Un navegador de escritorio actual, que precarga miles de certificados intermedios y buscará un emisor faltante si es necesario. El cliente más indulgente que posees
- Lo que usó tu visitante
- Algo más estricto o antiguo, que valida solo lo que se le entregó y reporta un emisor desconocido cuando la cadena no llega a una raíz
Entonces la tolerancia es una decisión del cliente en lugar de una propiedad de tu configuración, y has estado probando con el cliente más probable que te perdone.
Los informes que esto realmente genera
Debido a que los clientes indulgentes son los navegadores, los fallos aterrizan en otro lugar, y rara vez llegan descritos como un problema de certificado.
- Un webhook deja de entregarse. El servidor de otra persona ahora es el cliente, y no tiene una lista precargada ni interés en obtener tu emisor.
- Una aplicación móvil no puede iniciar sesión mientras que la misma cuenta funciona en la web, porque la pila de redes de la aplicación no es el navegador del sistema.
- Una integración de pago o envío falla contra tu URL de devolución de llamada, generalmente con un mensaje sobre un emisor desconocido o no confiable.
- Una oficina u otro dispositivo antiguo no puede acceder al sitio en absoluto, mientras que todos los demás pueden.
Ninguno de esos suena como “la cadena de certificados está incompleta”, que es por qué las horas se gastan en el lugar equivocado primero.
El certificado intermedio es la unidad de radio de explosión
Una razón más para saber de qué certificado intermedio dependes, separado de si lo envías.
Un certificado intermedio firma muchos certificados. Si uno se retira, se desconfía o se permite que expire, cada certificado bajo él deja de validarse en el mismo momento. Tu certificado puede estar a meses de su propio vencimiento, sin cambios, y aún así fallar, porque lo que se rompió es un nivel arriba y nunca fue tuyo.
La mayoría del monitoreo de certificados observa una única fecha: cuándo vence tu propio certificado. Esa es la fecha correcta para observar y no es la única, y la otra pertenece a un certificado que no elegiste y probablemente no puedes nombrar.
Verificarlo toma aproximadamente treinta segundos
Pregúntale al servidor qué realmente envía, desde algo que no sea tu navegador:
openssl s_client -showcerts -connect example.com:443 -servername example.com </dev/null
Dos cosas para leer en la salida. Cuenta los certificados: una cadena pública típica entrega tu certificado y al menos un certificado intermedio, por lo que exactamente un certificado es el síntoma clásico de este defecto. Luego lee el issuer de tu propio certificado y verifica que un certificado con ese subject esté presente más abajo.
Session Replay
Extensión Chrome gratuita. Un clic en la página que se está comportando mal captura la captura de pantalla, la consola y el registro de red, y te entrega un enlace para pegar en el ticket.
Si lo que te llega es una captura de pantalla de una pantalla de advertencia en su lugar, los cinco defectos diferentes detrás de esa página vale la pena separar antes de comenzar: tu conexión no es privada.
Qué sacar de esto
Un certificado es un enlace, no una credencial. Es de confianza porque se puede construir un camino desde él a algo en lo que el visitante ya confía, y tu servidor es responsable del medio de ese camino.
El modo de fallo es inusualmente cruel porque la compensación es tan buena. Los navegadores precarga miles de certificados intermedios y perseguirán un emisor faltante, por lo que el cliente con el que pruebas es el cliente menos probable que te lo diga. Los que te lo dicen son webhooks, aplicaciones móviles e integraciones de pagos, y te lo dicen con palabras que nunca mencionan certificados.
Las especificaciones son RFC 8446 para lo que un servidor debe enviar y RFC 5280 para el campo que nombra la ubicación de un emisor.