Guía práctica · Traefik
Traefik sirve el certificado equivocado: comprueba SNI, routers y ACME
Tu nombre de host apunta a Traefik, pero el navegador recibe un certificado predeterminado o emitido para otro nombre. Empieza con una nueva conexión TLS. El certificado se selecciona antes del enrutamiento HTTP, por lo que una regla Host correcta no demuestra por sí sola que el certificado esperado esté disponible.
Esta guía se aplica a Traefik v3 cuando termina la conexión HTTPS, con ejemplos de Docker Compose y del proveedor de archivos. Sustituye example.com, 192.0.2.10, las rutas y los nombres de servicios por los tuyos. Los comandos requieren Linux, Bash, OpenSSL y GNU timeout. Comprueba solo los puntos de terminación que administras o tienes autorización para examinar. La demostración local se probó con Traefik 3.7.16.
1. Examinar el certificado con el SNI correcto
Ejecuta la prueba desde fuera de la red de alojamiento. Conserva el nombre de host en -servername aunque -connect use una dirección IP. Anota la huella SHA-256, el emisor, las fechas de validez y las entradas Subject Alternative Name. Este comando muestra un certificado; no valida la confianza en la cadena ni la coincidencia del nombre de host.
set -o pipefail
timeout 10 openssl s_client -connect example.com:443 \
-servername example.com </dev/null |
openssl x509 -noout -sha256 -fingerprint \
-issuer -dates -ext subjectAltName Un certificado predeterminado puede indicar que ningún certificado cargado coincide con el SNI o que el cliente no envió SNI. Si la comprobación estricta de SNI está activada, Traefik puede rechazar la conexión. Si no aparece ningún certificado, investiga el error de conexión. Añadir una cabecera HTTP Host no cambia el certificado seleccionado previamente durante la negociación TLS.
2. Comprobar el router HTTPS y su resolver de certificados
Si Traefik gestiona los certificados ACME de tu aplicación Docker, revisa las etiquetas del contenedor de la aplicación en ejecución. El router debe utilizar el punto de entrada previsto y tener TLS activado. El valor certresolver debe nombrar un resolver existente, salvo que lo herede del punto de entrada. Estas etiquetas son un fragmento para adaptar a una aplicación existente; no configuran su puerto de destino ni el proveedor Docker.
labels:
- "traefik.http.routers.app.rule=Host(`example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls=true"
- "traefik.http.routers.app.tls.certresolver=letsencrypt" El resolver se declara en la configuración estática de Traefik. El siguiente ejemplo de desafío HTTP también define los puntos de entrada. Adapta la dirección de contacto y la ruta de almacenamiento persistente. Para este desafío, el puerto público 80 debe llegar al punto de entrada web. Si utilizas validación DNS u otro desafío, conserva la configuración correspondiente.
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /data/acme.json
httpChallenge:
entryPoint: web Declarar un resolver no lo asocia automáticamente a todos los routers. Los cambios en la configuración estática requieren reiniciar Traefik; un proveedor puede actualizar su configuración dinámicamente. Comprueba la configuración activa y los errores antes de reiniciar. Una regla HTTP Host puede proporcionar los nombres que se solicitan a ACME, mientras que SNI selecciona el certificado presentado en cada conexión TLS.
3. Distinguir un fallo ACME de un problema de selección
Si Traefik obtiene los certificados, consulta sus registros recientes. En este ejemplo Compose el servicio se llama traefik. Busca un resolver desconocido, un desafío fallido, un emisor de pruebas o un error de permisos de almacenamiento. Resuelve el error indicado antes de volver a solicitar un certificado.
docker compose logs --since=30m traefik El archivo acme.json configurado contiene claves privadas y datos de la cuenta ACME. Mantenlo privado, persistente al sustituir contenedores y accesible para Traefik con los permisos de archivo requeridos (600). No lo borres como atajo para solucionar el problema ni lo compartas entre instancias Traefik que se ejecuten a la vez. Un registro de emisión correcta acredita la emisión, no el certificado servido por cada dirección pública.
4. Si utilizas archivos, comprobar las rutas cargadas
Sigue esta rama si otra herramienta emite los certificados. Revisa tls.certificates en la configuración dinámica por archivos y comprueba que certFile y keyFile existan en esas rutas dentro del contenedor Traefik. El certificado debe cubrir el nombre solicitado y corresponder a su clave privada. El ejemplo siguiente es un fragmento de configuración dinámica, no una instalación completa de Traefik.
tls:
certificates:
- certFile: /certs/example.com/fullchain.pem
keyFile: /certs/example.com/privkey.pem Activa el proveedor de archivos con watch: true en la configuración estática. Con montajes bind, monta el directorio padre para que puedan detectarse los cambios. La demostración modifica la configuración dinámica para referenciar una nueva pareja de certificado y clave, y sustituye el archivo de configuración de forma atómica. Tras renovar, comprueba que Traefik haya cargado la actualización; sustituir un archivo en el disco no demuestra que haya cambiado el certificado servido.
5. Reproducir un certificado predeterminado en local
El script descargable inicia Traefik en 127.0.0.1 con un puerto asignado automáticamente. Crea certificados autofirmados para fallback.test, unrelated.test y renewal.test. Al principio solo están configurados el certificado unrelated y el de respaldo. La prueba de renewal.test recibe el de respaldo. El script carga después el certificado correcto mediante el proveedor de archivos y comprueba una nueva conexión sin reiniciar Traefik.
Descargar y revisar la demostración de Traefik
Requisitos: Linux, Bash, OpenSSL, GNU timeout y un motor Docker local. Docker puede descargar la imagen fijada. Lee el script y ejecuta bash traefik-certificate-selection.sh. BEFORE muestra la huella de respaldo; CONTROL muestra el certificado unrelated seleccionado por su SNI; AFTER muestra el certificado correcto. NO_SNI sigue mostrando el de respaldo. El script comprueba las huellas y que la hora de inicio del contenedor no haya cambiado. Elimina las claves temporales y el contenedor al terminar. La prueba comprueba la selección y la carga dinámica, no la emisión ni la renovación ACME.
6. Comprobar las conexiones públicas y mantener la vigilancia
Prueba cada dirección pública pertinente conservando el nombre de host como SNI. Sustituye la dirección de ejemplo de abajo; para IPv6, usa [dirección]:443. Un CDN puede terminar TLS antes de Traefik y presentar su propio certificado. Con TLS passthrough en un router TCP, el servidor de destino presenta el certificado. Comprueba el componente que termina cada conexión. Distintas instancias, rutas IPv4/IPv6 o negociaciones RSA/ECDSA pueden producir observaciones diferentes.
set -o pipefail
timeout 10 openssl s_client -connect 192.0.2.10:443 \
-servername example.com </dev/null |
openssl x509 -noout -sha256 -fingerprint \
-issuer -dates -ext subjectAltName Nocert observa periódicamente los certificados servidos por los puntos de terminación TLS accesibles y evalúa las reglas de aviso de caducidad en un ciclo diario. Comprueba el punto de terminación y la fecha de observación, y configura los destinatarios de los avisos. Esta vigilancia complementa la prueba externa inmediata. Nocert no configura tu resolver Traefik, no renueva certificados ni garantiza que todos los visitantes reciban el mismo certificado.