Renouveler automatiquement ses certificats SSL (Let’s Encrypt) avec Certbot – guide simple
Salut ! Ici je te montre comment je vérifie et j’automatise le renouvellement de mes certificats SSL Let’s Encrypt avec Certbot, sans rien casser. On va prendre exemple.com
comme domaine de démo, mais tu remplaces par le tien. Objectif : que ça se renouvèle tout seul et que tu dormes tranquille 😎
1) Vérifier l’installation et l’état des certificats
Certbot installé ?
certbot --version
Voir tous les certificats et leurs dates :
sudo certbot certificates
Tu obtiens la liste des certs, leurs domaines, chemins, et dates d’expiration.
2) Tester le renouvellement “sans risque” (dry-run)
C’est la commande magique : elle simule un renouvellement de tous tes certificats. Rien n’est modifié.
sudo certbot renew --dry-run
OK ➜ tu verras “Congratulations, all renewals succeeded” 🎉
Pas OK ➜ lis l’erreur, on corrige plus bas.
3) Éviter le conflit du port 80 : utiliser le plugin Apache ou Nginx
Si tu vois une erreur du style :
Problem binding to port 80: Could not bind to IPv4 or IPv6
c’est que le mode standalone
tente de prendre le port 80 alors qu’Apache/Nginx l’utilise déjà. La solution la plus propre : passer en plugin webserver.
Avec Apache :
sudo certbot renew --cert-name exemple.com --apache --dry-run
# puis en vrai si OK :
sudo certbot renew --cert-name exemple.com --apache
Avec Nginx :
sudo certbot renew --cert-name exemple.com --nginx --dry-run
# puis en vrai si OK :
sudo certbot renew --cert-name exemple.com --nginx
Le plugin crée une conf temporaire pour le challenge ACME. Zéro downtime.
4) S’assurer que l’auto-renouvellement est actif (systemd)
Voir le timer :
systemctl list-timers | grep certbot
Voir les derniers runs :
journalctl -u certbot.service --since "1 day ago" --no-pager
Rejouer maintenant (test) :
sudo systemctl start certbot.service
journalctl -u certbot.service -n 50 --no-pager
Sur la plupart des distros, le service lance certbot -q renew
deux fois par jour.
5) Recharger Apache automatiquement seulement si un cert est renouvelé
Un petit “deploy-hook” propre : il se déclenche uniquement si un certificat a réellement été renouvelé.
sudo install -Dm755 /dev/stdin /etc/letsencrypt/renewal-hooks/deploy/000-reload-apache.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if systemctl is-active --quiet apache2; then
systemctl reload apache2
fi
EOF
6) Vérifier côté public la validité (dates du certificat)
Utile pour confirmer ce qui est servi sur le port 443 :
echo | openssl s_client -servername exemple.com -connect exemple.com:443 2>/dev/null | openssl x509 -noout -issuer -subject -dates
7) Bonnes pratiques Apache/Nginx pour le challenge ACME
Si tu forces la redirection 80 ➜ 443, pense à laisser passer le chemin ACME :
Apache (VirtualHost :80)
# Laisse passer le challenge
Alias /.well-known/acme-challenge/ /var/www/html/.well-known/acme-challenge/
<Directory "/var/www/html/.well-known/acme-challenge/">
Options None
AllowOverride None
Require all granted
ForceType text/plain
</Directory>
# Ta redirection doit ignorer ce chemin
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Puis recharger
# sudo apachectl configtest && sudo systemctl reload apache2
Nginx (server port 80)
location ^~ /.well-known/acme-challenge/ {
root /var/www/html; # adapte au webroot
default_type "text/plain";
try_files $uri =404;
}
# sudo nginx -t && sudo systemctl reload nginx
8) Cas particuliers & “plan B”
Serveur non accessible publiquement en 80/443 (derrière NAT, home lab)
Utilise le challenge DNS-01 avec le plugin de ton DNS (Cloudflare, OVH, Gandi, Route53, etc.). Exemple générique Cloudflare :
# Installer le plugin (selon ta distrib)
sudo apt-get install python3-certbot-dns-cloudflare -y
# Token API dans un fichier privé
sudo bash -c 'cat >/etc/letsencrypt/cloudflare.ini <<EOF
dns_cloudflare_api_token = VOTRE_TOKEN_API
EOF'
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
# Test
sudo certbot certonly --dry-run \
--dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d exemple.com -d www.exemple.com
Si tu veux garder « standalone »
Arrêter Apache/Nginx uniquement le temps du challenge (je le fais rarement, mais ça dépanne) :
sudo certbot renew --cert-name exemple.com --standalone \
--pre-hook "systemctl stop apache2 || systemctl stop nginx" \
--post-hook "systemctl start apache2 || systemctl start nginx" \
--dry-run
9) Dépannage rapide (ce qui casse le plus souvent)
- Conflit port 80 : bascule en
--apache
ou--nginx
(section 3). - Redirection 80 ➜ 443 trop stricte : exclure
/.well-known/acme-challenge/
(section 7). - Firewall : laisser passer le port 80 (même si tu forces le HTTPS) pour le challenge HTTP-01.
- Domaine derrière un proxy/CDN : préfère DNS-01 avec un token API.
- Cert corrompu ou manquant : ré-émets proprement avec le plugin du webserver :
sudo certbot certonly --apache -d exemple.com -d www.exemple.com
# ou :
sudo certbot certonly --nginx -d exemple.com -d www.exemple.com
10) Récap express (les 4 commandes que j’utilise tout le temps)
# Voir l'état de tous les certs
sudo certbot certificates
# Tester sans risque
sudo certbot renew --dry-run
# Vérifier l'auto-run
systemctl list-timers | grep certbot
# Derniers logs
journalctl -u certbot.service --since "1 day ago" --no-pager
Et voilà ! Normalement, tu es en pilote automatique. Si tu as un doute, relance un --dry-run
, ça ne casse rien et ça rassure 😉
💡 Cet article t’a aidé ? Il t’a permis de résoudre tes problèmes de certificats SSL ?
N’hésite pas à laisser un petit commentaire pour dire merci et partager ton expérience 🙌