Renouvellement automatique SSL
Ce guide explique comment configurer le renouvellement automatique des certificats SSL Let's Encrypt.
Vérifier l'état actuel
Certificats installés
sudo certbot certificates
Exemple de sortie :
Certificate Name: mondomaine.com
Domains: mondomaine.com www.mondomaine.com
Expiry Date: 2024-03-15 10:30:00+00:00 (VALID: 45 days)
Certificate Path: /etc/letsencrypt/live/mondomaine.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/mondomaine.com/privkey.pem
Vérifier l'expiration d'un certificat
# Via certbot
sudo certbot certificates | grep -A 3 "Certificate Name"
# Via openssl (sur un domaine)
echo | openssl s_client -servername mondomaine.com -connect mondomaine.com:443 2>/dev/null | openssl x509 -noout -dates
# Via openssl (fichier local)
sudo openssl x509 -enddate -noout -in /etc/letsencrypt/live/mondomaine.com/cert.pem
Renouvellement automatique avec Certbot
Vérifier le timer systemd
Certbot installe automatiquement un timer :
# Vérifier que le timer est actif
sudo systemctl status certbot.timer
# Voir les timers programmés
sudo systemctl list-timers | grep certbot
Tester le renouvellement
# Test sans renouveler réellement
sudo certbot renew --dry-run
Si le test réussit, le renouvellement automatique fonctionnera.
Configuration du renouvellement
Le fichier de configuration se trouve dans /etc/letsencrypt/renewal/mondomaine.com.conf :
[renewalparams]
authenticator = nginx
account = xxxxxxxxxxxxx
server = https://acme-v02.api.letsencrypt.org/directory
[webroot]
# ou autres options selon votre configuration
Hooks de renouvellement
Les hooks permettent d'exécuter des commandes avant/après le renouvellement.
Structure des hooks
/etc/letsencrypt/renewal-hooks/
├── pre/ # Avant le renouvellement
├── deploy/ # Après un renouvellement réussi
└── post/ # Après le renouvellement (succès ou échec)
Hook pour recharger Nginx
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Hook pour recharger Apache
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh
#!/bin/bash
systemctl reload apache2
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh
Hook de notification
sudo nano /etc/letsencrypt/renewal-hooks/deploy/notify.sh
#!/bin/bash
DOMAIN=$RENEWED_DOMAINS
EXPIRY=$(openssl x509 -enddate -noout -in "$RENEWED_LINEAGE/cert.pem" | cut -d= -f2)
# Notification par email
echo "Le certificat pour $DOMAIN a été renouvelé. Nouvelle expiration: $EXPIRY" | \
mail -s "SSL renouvelé: $DOMAIN" admin@votredomaine.com
# Notification Discord (optionnel)
curl -H "Content-Type: application/json" \
-d "{\"content\": \"Le certificat SSL pour **$DOMAIN** a été renouvelé. Expire le: $EXPIRY\"}" \
"VOTRE_WEBHOOK_DISCORD"
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/notify.sh
Renouvellement avec Cron (alternative)
Si le timer systemd ne fonctionne pas :
sudo crontab -e
# Renouvellement SSL 2x par jour
0 3,15 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Monitoring des certificats
Script de vérification
sudo nano /usr/local/bin/check-ssl.sh
#!/bin/bash
ALERT_DAYS=14
EMAIL="admin@votredomaine.com"
for cert in /etc/letsencrypt/live/*/cert.pem; do
DOMAIN=$(basename $(dirname $cert))
EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $ALERT_DAYS ]; then
echo "ALERTE: $DOMAIN expire dans $DAYS_LEFT jours ($EXPIRY_DATE)" | \
mail -s "SSL ALERTE: $DOMAIN" $EMAIL
fi
echo "$DOMAIN: $DAYS_LEFT jours restants"
done
sudo chmod +x /usr/local/bin/check-ssl.sh
Ajouter au cron :
# Vérification quotidienne à 9h
0 9 * * * /usr/local/bin/check-ssl.sh
Monitoring avec curl
Vérifier un certificat distant :
#!/bin/bash
# check-remote-ssl.sh
DOMAIN="$1"
ALERT_DAYS=14
EXPIRY=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | \
openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "$DOMAIN: $DAYS_LEFT jours restants (expire le $EXPIRY)"
if [ $DAYS_LEFT -lt $ALERT_DAYS ]; then
exit 1 # Pour alerter dans un système de monitoring
fi
Dépannage
Le renouvellement échoue
Erreur de validation HTTP
# Vérifier que le challenge est accessible
curl http://mondomaine.com/.well-known/acme-challenge/test
# Vérifier la configuration Nginx
location /.well-known/acme-challenge/ {
root /var/www/html;
}
Port 80 bloqué
# Vérifier que le port 80 est ouvert
sudo ufw status | grep 80
sudo ufw allow 80/tcp
Trop de tentatives (rate limit)
Let's Encrypt limite à 5 échecs par heure. Attendez avant de réessayer.
# Utiliser le serveur de staging pour les tests
sudo certbot certonly --staging -d mondomaine.com
Forcer le renouvellement
# Renouveler un certificat spécifique
sudo certbot renew --cert-name mondomaine.com --force-renewal
# Renouveler tous les certificats
sudo certbot renew --force-renewal
Vérifier les logs
# Logs Certbot
sudo cat /var/log/letsencrypt/letsencrypt.log
# Logs récents
sudo journalctl -u certbot -f
Certificats Wildcard
Les certificats wildcard nécessitent une validation DNS :
sudo certbot certonly --manual --preferred-challenges dns -d "*.mondomaine.com" -d "mondomaine.com"
Automatisation avec API DNS
Pour Cloudflare :
sudo apt install python3-certbot-dns-cloudflare
Créer le fichier de credentials :
sudo nano /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = VOTRE_TOKEN_API
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
Obtenir le certificat :
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.mondomaine.com" \
-d "mondomaine.com"
Bonnes pratiques
- Toujours tester avec
--dry-runavant de modifier la configuration - Configurer des alertes pour être prévenu avant l'expiration
- Utiliser les hooks deploy plutôt que post pour les actions post-renouvellement
- Garder le port 80 ouvert même si vous redirigez vers HTTPS
- Monitorer les logs régulièrement
Les certificats Let's Encrypt sont valides 90 jours. Certbot renouvelle automatiquement quand il reste moins de 30 jours.