Toutes les ressources

Guide pratique · acme.sh + Nginx

acme.sh : certificat renouvelé, mais Nginx sert encore l’ancien

Un renouvellement réussi ne prouve pas que votre service HTTPS a chargé le nouveau certificat. Avec acme.sh, vérifiez l’entrée du certificat, les fichiers de destination enregistrés par --install-cert et la commande de rechargement avant de demander un autre certificat.

Ce guide utilise acme.sh avec Nginx sous Linux. L’exemple de service suppose systemd ; adaptez les chemins, les noms de services et les droits à votre déploiement. Les commandes de diagnostic utilisent Bash, OpenSSL et GNU timeout. Exécutez acme.sh avec le compte et les répertoires de configuration de votre installation existante. La démonstration locale a été testée avec acme.sh 3.1.6 et Nginx 1.31.8.

1. Retrouver le certificat géré par le renouvellement

Listez les certificats, puis examinez l’entrée concernée. Remplacez example.com par le nom principal du certificat. Les exemples avec --ecc sélectionnent un certificat ECC ; retirez cette option des commandes pour une entrée RSA. Si vous utilisez des chemins --home, --config-home ou --cert-home personnalisés, conservez-les dans chaque commande pour interroger la bonne installation.

"$HOME/.acme.sh/acme.sh" --list
"$HOME/.acme.sh/acme.sh" --info -d example.com --ecc

Examinez Le_RealKeyPath, Le_RealFullChainPath et Le_ReloadCmd, ainsi que les informations d’émission et de renouvellement. Gardez cette sortie privée : la configuration et les commandes peuvent contenir des valeurs sensibles. Vérifiez le compte, la planification et les journaux de la tâche de renouvellement. Un échec d’émission demande son propre diagnostic ; un nouveau certificat valide accompagné d’une erreur d’installation ne justifie pas de forcer des renouvellements répétés.

2. Faire correspondre les destinations aux chemins de Nginx

Utilisez des fichiers de destination dédiés à Nginx. Le répertoire de travail interne d’acme.sh n’est pas une interface de déploiement stable. Vérifiez les chemins de la configuration active, ainsi que les montages de conteneurs si nécessaire. Cet extrait s’insère dans un bloc serveur HTTPS existant.

ssl_certificate     /etc/nginx/tls/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/tls/example.com/key.pem;

Lisez le certificat public à l’emplacement configuré et relevez son empreinte SHA-256, ses dates de validité et ses SAN. La chaîne complète doit contenir le certificat du serveur en premier, suivi de ses intermédiaires.

openssl x509 -in /etc/nginx/tls/example.com/fullchain.pem \
  -noout -sha256 -fingerprint -issuer -dates -ext subjectAltName

Un fichier interne acme.sh à jour ne prouve pas que cette destination a été mise à jour. Une destination à jour ne prouve pas que Nginx l’a chargée. Conservez la clé privée confidentielle et vérifiez que le processus qui la charge dispose des droits nécessaires.

3. Enregistrer les bons chemins et la commande de rechargement

La commande suivante modifie immédiatement les fichiers et recharge Nginx. Utilisez-la après avoir vérifié les destinations et l’entrée du certificat. Préparez le répertoire de destination avec le propriétaire et les permissions adaptés. Le compte qui exécute acme.sh doit pouvoir écrire ces fichiers et lancer le rechargement sans intervention.

"$HOME/.acme.sh/acme.sh" --install-cert -d example.com --ecc \
  --key-file /etc/nginx/tls/example.com/key.pem \
  --fullchain-file /etc/nginx/tls/example.com/fullchain.pem \
  --reloadcmd "/usr/sbin/nginx -t && /usr/bin/systemctl reload nginx"

Adaptez les chemins absolus des exécutables et l’unité systemd. Le && empêche le rechargement si nginx -t échoue. acme.sh mémorise les destinations et la commande pour les prochains renouvellements. Le propriétaire et les permissions des fichiers de destination existants sont conservés. Contrôlez le code de retour et les journaux : un échec de rechargement peut laisser les nouveaux fichiers sur disque alors que l’ancien certificat reste servi. Corrigez la cause, puis relancez --install-cert avec les paramètres prévus. En conteneur, la commande doit atteindre le processus Nginx concerné, pas un service homonyme sur l’hôte.

4. Vérifier le certificat reçu en TLS

Depuis l’extérieur du réseau d’hébergement, ouvrez une nouvelle connexion TLS vers un service que vous administrez ou êtes autorisé à examiner. Conservez le nom d’hôte comme SNI et comparez l’empreinte au fichier de destination. Cette commande affiche le certificat ; elle ne valide ni la confiance dans la chaîne ni la correspondance du nom d’hôte.

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

Si les empreintes diffèrent, repérez le composant qui termine TLS. Un CDN ou un load balancer peut servir son propre certificat. Vérifiez les adresses publiques et les accès à l’origine concernés ; utilisez IP:443 ou [IPv6]:443 avec -connect en conservant le nom d’hôte dans -servername. Plusieurs réplicas ou certificats RSA/ECDSA peuvent produire des observations différentes. Si le certificat attendu est servi mais refusé par le navigateur, examinez la chaîne et les noms couverts.

5. Reproduire un échec de rechargement localement

Le script exécute réellement acme.sh --install-cert avec des certificats autosignés temporaires. Nginx sert d’abord l’ancien certificat. Une commande de rechargement volontairement en échec laisse acme.sh copier les nouveaux fichiers, mais renvoie une erreur. Une seconde installation avec une commande fonctionnelle fait servir le nouveau certificat par Nginx.

Télécharger et examiner la démonstration acme.sh

Prérequis : Linux, Bash, un moteur Docker local, curl, OpenSSL et GNU coreutils. Le script télécharge une version figée d’acme.sh, vérifie son empreinte de contrôle et utilise une image Nginx épinglée. Lisez-le, puis lancez bash acme-sh-install-reload.sh.

BEFORE et SERVED indiquent l’ancienne empreinte ; DISK indique la nouvelle ; AFTER doit correspondre à DISK. Des assertions vérifient aussi les chemins et la commande enregistrés, ainsi que la conservation des permissions du fichier de clé. Le script utilise un répertoire acme.sh temporaire et un port sur la boucle locale, puis supprime son conteneur et ses fichiers temporaires. Il n’installe aucune tâche cron. L’image Docker reste en cache.

Seul ce test, lié à une version précise, prépare l’état interne d’acme.sh avec des fichiers synthétiques. Ne reproduisez pas cette préparation dans un stockage réel de certificats. La démonstration vérifie l’installation, la gestion de l’erreur et le rechargement, pas l’émission ACME, la planification des renouvellements ou la confiance des navigateurs publics.

6. Maintenir le suivi après le contrôle immédiat

Relevez l’adresse, le SNI, l’heure et l’empreinte observés après déploiement. Confirmez que la tâche de renouvellement utilise les mêmes chemins et dispose des droits nécessaires sans shell interactif. Faites remonter ses échecs dans votre supervision des tâches existante.

Nocert observe périodiquement les certificats servis par les points de terminaison TLS accessibles et évalue les règles d’alerte d’expiration selon un cycle quotidien. Vérifiez le point de terminaison et l’heure d’observation, puis configurez les destinataires. Ce suivi complète le contrôle externe immédiat. Nocert n’exécute pas acme.sh, n’installe pas les certificats et ne recharge pas Nginx. Il ne garantit pas que tous les visiteurs reçoivent le même certificat.

Sources techniques