Guía práctica · Certbot + Nginx
Certbot ha renovado el certificado, pero Nginx sigue sirviendo el anterior
Certbot ha guardado un certificado nuevo. Sin embargo, una conexión TLS externa sigue recibiendo el anterior. Antes de solicitar otra renovación, comprueba qué archivo carga Nginx, qué servidor responde y si la recarga se completó.
Esta guía se aplica a Linux con Bash, OpenSSL, Certbot y Nginx gestionado por systemd, con rutas de certificados estáticas. Sustituye example.com y el nombre del certificado por los tuyos. Si utilizas contenedores, un CDN o un balanceador, comprueba el componente que termina realmente la conexión TLS.
1. Identificar el certificado del disco
En el servidor Nginx, enumera los certificados gestionados por Certbot. Utiliza el Certificate Name que aparece: puede ser distinto del dominio, por ejemplo example.com-0001. Lee el certificado del servidor en ese directorio y anota su huella SHA-256, número de serie y fechas de validez. Nunca copies la clave privada en un informe de diagnóstico.
sudo certbot certificates
sudo openssl x509 \
-in /etc/letsencrypt/live/example.com/cert.pem \
-noout -sha256 -fingerprint -serial -dates Que certbot renew termine correctamente no demuestra que haya renovado un certificado: también termina con éxito cuando no hay ninguna renovación pendiente. Un dry run prueba la renovación con el servicio de pruebas; no sustituye el certificado de producción.
2. Abrir una nueva conexión TLS desde fuera
Ejecuta este comando desde otra máquina, fuera de la red de alojamiento. El nombre de host también se envía como SNI para que el servidor seleccione el host virtual adecuado. Este comando muestra el certificado presentado; no valida la confianza en la cadena ni la coincidencia del nombre de host.
set -o pipefail
openssl s_client -connect example.com:443 \
-servername example.com </dev/null |
openssl x509 -noout -sha256 -fingerprint -serial -dates Compara las huellas SHA-256, no solo las fechas. Si coinciden, esta conexión ha recibido el certificado que examinaste en el disco. Una diferencia indica otro certificado, pero no demuestra por sí sola que haya fallado la recarga de Nginx. Si la conexión falla o no aparece ningún certificado, investiga primero ese error.
3. Comprobar dónde termina TLS y recargar Nginx
Consulta la configuración efectiva localmente con sudo nginx -T. Localiza las directivas server_name, listen, ssl_certificate y ssl_certificate_key para ese nombre de host. La salida puede contener secretos: no la publiques. Con Certbot, la ruta habitual termina en live/<certificate-name>/fullchain.pem; una ruta archive antigua o una copia del archivo no se actualiza automáticamente con cada renovación.
sudo nginx -t && sudo systemctl reload nginx Si systemd gestiona Nginx en este servidor, valida la configuración antes de recargarlo. Si falla alguno de los comandos, consulta el registro del servicio y el registro de errores de Nginx. Repite después la comprobación externa con una nueva conexión y vuelve a comparar las huellas. La renovación y el despliegue correcto se comprueban por separado.
4. Incorporar la recarga al despliegue
Si utilizas certonly con validación webroot o DNS y gestionas tú el despliegue en Nginx, utiliza un deploy hook tras una renovación correcta. En una instalación Linux habitual, guarda el siguiente script con permiso de ejecución en /etc/letsencrypt/renewal-hooks/deploy/reload-nginx. Comprueba las rutas de los ejecutables y prueba el script con sudo. El instalador Nginx de Certbot puede encargarse ya del despliegue: revisa la configuración existente antes de añadir otro mecanismo.
#!/bin/sh
set -eu
/usr/sbin/nginx -t
/usr/bin/systemctl reload nginx Certbot renew --dry-run no ejecuta los deploy hooks por defecto. La opción --run-deploy-hooks los ejecuta durante la prueba y puede recargar el servicio de producción con el certificado activo. Planifica esa prueba teniendo en cuenta este efecto. Evita repetir --force-renewal para resolver un problema de despliegue.
5. Reproducir la diferencia en local
El script Bash descargable inicia un contenedor Nginx aislado, accesible por 127.0.0.1 en un puerto asignado automáticamente. Crea dos certificados autofirmados para renewal.test, sustituye los archivos y compara la huella servida antes y después de recargar. Simula la sustitución de archivos, no la emisión ACME. Requisitos: Linux, un motor Docker local y OpenSSL; Docker puede descargar la imagen Nginx fijada.
Descargar y revisar el script de demostración
Tras leer el archivo descargado, ejecuta bash nginx-certificate-reload.sh sin sudo si tu configuración Docker lo permite. BEFORE y SERVED deben coincidir; DISK debe ser diferente. AFTER debe coincidir con DISK. El script comprueba estas condiciones y elimina su contenedor y sus claves temporales al terminar. No modifica tu servicio Nginx.
6. Comprobar las demás rutas y mantener la vigilancia
Un CDN puede servir un certificado distinto del servidor de origen sin que exista un error. Prueba ambas conexiones TLS por separado. Si hay varios servidores o IPv4/IPv6, comprueba cada dirección pertinente conservando el mismo nombre SNI. Una comprobación correcta no cubre todos los servidores, rutas de red o visitantes. Si usas certificados RSA y ECDSA separados, compara el que corresponda a la negociación realizada. En el siguiente ejemplo, sustituye 192.0.2.10 por la dirección que tienes autorización para comprobar. Para IPv6, usa [dirección]:443 en -connect.
openssl s_client -connect 192.0.2.10:443 \
-servername example.com </dev/null |
openssl x509 -noout -sha256 -fingerprint -serial -dates 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 comprobación externa inmediata; no emite certificados, no recarga Nginx ni certifica el despliegue correcto de cada renovación de Certbot.