Mensaje de error
x509: certificate is valid for example.com, not api.example.com
Los dos nombres se rellenan en cada fallo: primero, los nombres que cubre el certificado; después, el nombre que pidió tu cliente.
Go crypto/x509 — HostnameError from VerifyHostname / TLS dials
Qué significa
La conexión TLS avanzó lo suficiente para leer el certificado, pero ninguno de sus nombres alternativos del sujeto (SAN) coincide con el nombre de host al que se conectó el cliente. El error muestra ambos lados, así que la diferencia se ve de inmediato: el certificado cubre X y tú pides Y. Ten en cuenta que la verificación moderna usa solo los SAN; el campo heredado de nombre común (Common Name) se ignora.
Por qué ocurre
Falta en la lista SAN el nombre que se usa
frecuenteUn certificado emitido para example.com no cubre api.example.com (y un comodín *.example.com cubre un solo nivel: ni example.com en sí ni a.b.example.com). Los subdominios nuevos necesitan certificados reemitidos.
Conexión a un alias interno
frecuenteAl conectarte a un nombre de servicio de docker-compose o a otro alias interno, el servidor presenta el certificado de lo que cree ser: los SAN contienen nombres DNS públicos, no tu alias, así que la coincidencia falla. Si te conectas a una dirección IP sin más, el fallo llega con un mensaje hermano: «x509: cannot validate certificate for 10.0.0.5 because it doesn't contain any IP SANs».
Se sirve un certificado incorrecto o el predeterminado (SNI)
ocasionalLos ingress multiinquilino eligen el certificado según el SNI. Un cliente que omite ServerName, o un ingress sin regla para el host, recibe el certificado predeterminado, que a menudo es uno provisional como «Kubernetes Ingress Controller Fake Certificate».
Cómo solucionarlo
- 1.
Volver a emitir con todos los nombres que usas realmente
Añade todos los nombres de host como SAN al emitir el certificado; revisa la lista SAN actual para ver qué está cubierto hoy.
bash echo | openssl s_client -connect host:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName # request with SANs: openssl req -new -key key.pem -out req.csr \ -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:api.example.com" - 2.
Conectarse por el nombre o fijar ServerName explícitamente
Cuando la dirección de red tiene que ser distinta del nombre del certificado (VIP, redirección de puertos, sidecar), mantén la verificación rigurosa indicándole a TLS qué identidad esperas.
go conn, err := tls.Dial("tcp", "10.0.0.5:443", &tls.Config{ ServerName: "api.example.com", // matched against SANs, sent as SNI })