Toutes les ressources

Guide pratique · Certbot + Nginx

Certbot a renouvelé le certificat, mais Nginx sert encore l’ancien

Certbot a écrit un nouveau certificat. Pourtant, une connexion TLS externe reçoit encore l’ancien. Vérifiez le fichier chargé par Nginx, le serveur qui répond et le résultat du rechargement avant de demander un nouveau renouvellement.

Ce guide concerne Linux avec Bash, OpenSSL, Certbot et Nginx géré par systemd, avec des chemins de certificats statiques. Remplacez example.com et le nom du certificat par les vôtres. Avec des conteneurs, un CDN ou un répartiteur de charge, vérifiez le composant qui termine réellement la connexion TLS.

1. Identifier le certificat sur disque

Sur le serveur Nginx, listez les certificats gérés par Certbot. Reprenez le Certificate Name affiché : il peut différer du domaine, par exemple example.com-0001. Lisez le certificat du serveur dans ce répertoire et relevez son empreinte SHA-256, son numéro de série et ses dates de validité. Ne copiez jamais la clé privée dans un compte rendu de diagnostic.

sudo certbot certificates
sudo openssl x509 \
  -in /etc/letsencrypt/live/example.com/cert.pem \
  -noout -sha256 -fingerprint -serial -dates

Le succès de certbot renew ne prouve pas qu’un certificat a été renouvelé : la commande réussit aussi lorsqu’aucun renouvellement n’est nécessaire. Un dry run teste le renouvellement auprès du service de test ; il ne remplace pas le certificat de production.

2. Ouvrir une nouvelle connexion TLS depuis l’extérieur

Exécutez cette commande depuis une autre machine, hors du réseau d’hébergement. Le nom d’hôte est aussi envoyé en SNI pour que le serveur choisisse le bon hôte virtuel. Cette commande affiche le certificat présenté ; elle ne valide ni la confiance dans la chaîne ni la correspondance du nom d’hôte.

set -o pipefail
openssl s_client -connect example.com:443 \
  -servername example.com </dev/null |
  openssl x509 -noout -sha256 -fingerprint -serial -dates

Comparez les empreintes SHA-256, pas seulement les dates. Si elles correspondent, cette connexion a reçu le certificat examiné sur disque. Une différence révèle un autre certificat, sans prouver à elle seule un échec du rechargement de Nginx. Si la connexion échoue ou qu’aucun certificat ne s’affiche, examinez d’abord cette erreur.

3. Vérifier où se termine TLS et recharger Nginx

Consultez localement la configuration effective avec sudo nginx -T. Repérez les directives server_name, listen, ssl_certificate et ssl_certificate_key correspondant au nom d’hôte. Cette sortie peut contenir des secrets : ne la publiez pas. Avec Certbot, le chemin habituel finit par live/<certificate-name>/fullchain.pem ; un ancien chemin archive ou un fichier copié ne suit pas automatiquement les renouvellements.

sudo nginx -t && sudo systemctl reload nginx

Pour Nginx géré par systemd sur ce serveur, validez la configuration avant de recharger le service. Si l’une des commandes échoue, consultez le journal du service et le journal d’erreurs Nginx. Refaites ensuite le contrôle externe avec une nouvelle connexion et comparez les empreintes. Le renouvellement et le bon déploiement se vérifient séparément.

4. Intégrer le rechargement au déploiement

Si vous utilisez certonly avec une validation webroot ou DNS et gérez vous-même le déploiement Nginx, utilisez un deploy hook après renouvellement réussi. Sur une installation Linux classique, placez le script exécutable ci-dessous dans /etc/letsencrypt/renewal-hooks/deploy/reload-nginx. Vérifiez les chemins des exécutables sur votre serveur et testez le script avec sudo. L’installateur Nginx de Certbot peut déjà gérer le déploiement : examinez la configuration existante avant d’ajouter un second mécanisme.

#!/bin/sh
set -eu
/usr/sbin/nginx -t
/usr/bin/systemctl reload nginx

Certbot renew --dry-run n’exécute pas les deploy hooks par défaut. L’option --run-deploy-hooks les exécute pendant le test et peut recharger le service de production avec le certificat actif. Planifiez ce test en conséquence. Évitez de répéter --force-renewal pour résoudre un problème de déploiement.

5. Reproduire le décalage en local

Le script Bash téléchargeable démarre un conteneur Nginx isolé, accessible sur 127.0.0.1 avec un port attribué automatiquement. Il crée deux certificats autosignés pour renewal.test, remplace les fichiers puis compare l’empreinte servie avant et après rechargement. Il simule le remplacement des fichiers, pas l’émission ACME. Prérequis : Linux, un moteur Docker local et OpenSSL ; Docker peut télécharger l’image Nginx épinglée.

Télécharger et examiner le script de démonstration

Après lecture du fichier téléchargé, lancez bash nginx-certificate-reload.sh sans sudo si votre configuration Docker le permet. BEFORE et SERVED doivent correspondre ; DISK doit différer. AFTER doit correspondre à DISK. Le script vérifie ces conditions et supprime son conteneur et ses clés temporaires à la sortie. Il ne modifie pas votre service Nginx.

6. Contrôler les autres chemins, puis surveiller

Un CDN peut servir un certificat différent de celui du serveur d’origine sans qu’il y ait d’erreur. Testez séparément ces deux connexions TLS. Avec plusieurs serveurs ou IPv4/IPv6, contrôlez chaque adresse pertinente en conservant le même nom SNI. Une sonde réussie ne couvre pas tous les serveurs, chemins réseau ou visiteurs. Si vous utilisez des certificats RSA et ECDSA distincts, comparez celui qui correspond à la négociation effectuée. Dans l’exemple ci-dessous, remplacez 192.0.2.10 par l’adresse que vous êtes autorisé à contrôler. Pour IPv6, utilisez [adresse]:443 dans -connect.

openssl s_client -connect 192.0.2.10:443 \
  -servername example.com </dev/null |
  openssl x509 -noout -sha256 -fingerprint -serial -dates

Nocert observe périodiquement les certificats servis par les points de terminaison TLS accessibles et évalue les règles d’alerte d’expiration lors d’un cycle quotidien. Vérifiez le point de terminaison et la date d’observation, puis configurez les destinataires des alertes. Cette surveillance complète le contrôle externe immédiat ; elle n’émet pas de certificats, ne recharge pas Nginx et ne certifie pas le bon déploiement de chaque renouvellement Certbot.

Sources techniques