Guide Let's Encrypt et Challenge DNS
Introduction
Ce guide décrit la mise en œuvre de certificats SSL/TLS Let's Encrypt via le protocole ACME DNS-01 challenge dans le contexte d'une infrastructure DNS gérée par SdV.
Types de certificats supportés
Vous pouvez générer trois types de certificats selon vos besoins :
| Type | Syntaxe | Usage |
|---|---|---|
| Simple | -d monsite.fr | Un seul domaine ou sous-domaine |
| Wildcard | -d *.monsite.fr | Tous les sous-domaines d'un domaine (nécessite DNS-01) |
| Multi-domaines (SAN) | -d monsite.fr -d aliasdemonsite.fr | Plusieurs domaines dans un même certificat |
Architecture et sécurité
API dédiée au challenge ACME
Afin d'augmenter le niveau de sécurité de vos domaines, SdV met à disposition une API spécifique et restreinte pour les challenges Let's Encrypt.
Endpoint API : https://certmanager-endpoint-dns.sdv.fr/dnsapi
Caractéristiques de sécurité :
- Principe de moindre privilège : Les clés d'API utilisées pour ACME DNS-01 sont différentes des clés de gestion complète du domaine
- Permissions limitées : Cette API ne permet que de créer et supprimer des enregistrements DNS de type
TXTpréfixés par_acme-challenge - Isolation : Aucune autre opération DNS (ajout A, CNAME, MX, suppression de zone, etc.) n'est possible avec ces clés
Fonctionnement du challenge DNS-01
Le challenge DNS-01 fonctionne en quatre étapes :
- Demande de certificat : CertBot envoie une demande à Let's Encrypt via le protocole ACME
- Challenge : Let's Encrypt génère un token aléatoire et demande de créer un enregistrement DNS
TXTsous_acme-challenge.monsite.frcontenant une valeur calculée - Validation : Let's Encrypt interroge les serveurs DNS autoritatifs pour vérifier la présence de cet enregistrement
- Émission : Si le challenge réussit, Let's Encrypt émet le certificat
┌─────────────┐ ┌──────────────────┐
│ CertBot │───── ACME ──────►│ Let's Encrypt │
│ (serveur) │ │ (CA Server) │
└──────┬──────┘ └────────┬─────────┘
│ │
│ 1. Hook authenticator │ 2. DNS Query
│ (créer TXT) │ _acme-challenge
▼ ▼
┌─────────────────────────────────────────────────────┐
│ API SdV DNS (certmanager-endpoint-dns) │
│ POST /dnsapi/v1/records │
│ { │
│ "type": "TXT", │
│ "name": "_acme-challenge.monsite.fr", │
│ "value": "base64_token_from_letsencrypt" │
│ } │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ Serveurs DNS autoritatifs SdV │
│ _acme-challenge.monsite.fr. 60 IN TXT "token..." │
└─────────────────────────────────────────────────────┘Prérequis
Composants nécessaires
Vous aurez besoin des éléments suivants :
- CertBot installé sur le serveur où le certificat sera généré
- Scripts SdV : Contenu du repository https://gitlab.sdv.fr/sdv_public/certbot_challenge_dns_sdv
- Clé API SdV : Permettant la gestion du challenge ACME DNS-01 sur vos domaines
- Permissions root : Les manipulations nécessitent les privilèges administrateur
- Connectivité réseau : Accès sortant vers l'API SdV et Let's Encrypt
Dépendances système
| Composant | Dépendances système |
|---|---|
| CertBot | Python 3.6+, pip, openssl |
| Scripts SdV | bash, curl, jq |
| API SdV | Accès HTTPS sortant (443) |
Installation
Installation de CertBot
apt-get update && apt-get install -y certbotInstallation des scripts SdV
Après avoir installé CertBot, téléchargez la dernière release des scripts SdV : télécharger.
Les scripts doivent être installés à l'emplacement /etc/certbot-sdv-scripts :
# Créer le répertoire
mkdir -p /etc/certbot-sdv-scripts
# Télécharger et extraire la release
wget https://gitlab.sdv.fr/sdv_public/certbot_challenge_dns_sdv/-/archive/v1.1.0/certbot_challenge_dns_sdv-v1.1.0.tar.bz2
tar xvjf certbot_challenge_dns_sdv-v1.1.0.tar.bz2 -C /etc/certbot-sdv-scripts --strip-components=1
# Nettoyer l'archive
rm -f certbot_challenge_dns_sdv-v1.1.0.tar.bz2Vous devriez alors avoir les fichiers suivants :
find /etc/certbot-sdv-scripts/
# /etc/certbot-sdv-scripts/
# /etc/certbot-sdv-scripts/sdv.ini
# /etc/certbot-sdv-scripts/debug.sh
# /etc/certbot-sdv-scripts/command.sample
# /etc/certbot-sdv-scripts/authenticator.sh
# /etc/certbot-sdv-scripts/check_env.sh
# /etc/certbot-sdv-scripts/cleanup.shSécurisation des scripts
Pour votre sécurité, les scripts doivent appartenir à root:root et n'être lisibles/exécutables que par root :
# Définir les permissions appropriées
chown -R root:root /etc/certbot-sdv-scripts/
chmod 700 /etc/certbot-sdv-scripts/
chmod 600 /etc/certbot-sdv-scripts/sdv.ini
chmod 700 /etc/certbot-sdv-scripts/*.sh
# Vérification
ls -la /etc/certbot-sdv-scripts/
# drwx------ 2 root root 4096 ... .
# -rw------- 1 root root 256 ... sdv.ini
# -rwx------ 1 root root 1024 ... authenticator.sh
# -rwx------ 1 root root 512 ... cleanup.shConfiguration
Fichier de configuration SdV
Éditez le fichier /etc/certbot-sdv-scripts/sdv.ini avec les paramètres suivants :
# Clé d'API fournie par SdV (obligatoire)
API_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# Email de contact pour notifications Let's Encrypt (obligatoire)
EMAIL="admin@monsite.fr"
# Endpoint de l'API SdV (obligatoire)
SdV_ENDPOINT="https://certmanager-endpoint-dns.sdv.fr/dnsapi"
# Fichier de logs pour le debug (optionnel)
CERTBOT_SdV_LOGS="/var/log/certbot-sdv-scripts.log"Paramètres de configuration
| Paramètre | Description | Obligatoire |
|---|---|---|
API_KEY | Clé d'authentification API SdV | Oui |
EMAIL | Contact pour expirations et alertes | Oui |
SdV_ENDPOINT | URL de l'API DNS SdV | Oui |
CERTBOT_SdV_LOGS | Chemin du fichier de logs | Non (défaut: /tmp/certbot-sdv-scripts.log) |
Obtention de la clé API
Informations requises
Pour obtenir votre clé API, contactez SdV via l'outil de ticket en fournissant :
- Liste des adresses IP sources autorisées à appeler l'API (serveurs CertBot)
- Liste des domaines concernés par la génération de certificats
- Environnement : production, préproduction, développement
- Contexte d'utilisation : CI/CD, génération manuelle, renouvellement automatisé
Modèle de périmètre
| Serveur | IP | Domaines gérés | Usage |
|---|---|---|---|
| prod-web-01 | 192.0.2.10 | *.monsite.fr, monsite.com | Production |
| preprod-web-01 | 192.0.2.20 | *.preprod.monsite.fr | Préproduction |
Stratégies de clés API
- Clé globale (par défaut) : Accès à tous les domaines de votre portefeuille SdV
- Clés par domaine : Une clé par domaine ou groupe de domaines (recommandé pour isolation)
- Clés par environnement : Séparation prod/preprod/dev pour limiter l'impact d'une fuite
Génération de certificats
Test en environnement staging
Avant de générer un certificat production, testez avec l'environnement staging de Let's Encrypt pour éviter de déclencher les rate limits :
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
--staging \
-d test.monsite.frOptions de la commande
| Option | Description |
|---|---|
certonly | Ne génère que le certificat (pas d'installation automatique) |
--manual | Mode manuel avec hooks personnalisés |
--preferred-challenges=dns | Force le challenge DNS-01 |
--manual-auth-hook | Script exécuté pour créer le record TXT |
--manual-cleanup-hook | Script exécuté pour supprimer le record TXT |
--staging | Utilise l'environnement de test Let's Encrypt |
-d | Spécifie le(s) domaine(s) |
Vérification du certificat généré
# Lister les certificats
certbot certificates
# Détails du certificat
openssl x509 -in /etc/letsencrypt/live/test.monsite.fr/cert.pem -text -noout
# Vérifier l'émetteur (doit contenir "Fake LE" en staging)
openssl x509 -in /etc/letsencrypt/live/test.monsite.fr/cert.pem -issuer -noout
# issuer=CN = (STAGING) Fake LE Intermediate X1Génération en production
Certificat simple
Une fois les tests validés en staging, générez le certificat production :
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
-d monsite.fr \
-d www.monsite.frCertificat wildcard
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
-d '*.monsite.fr' \
-d monsite.frCertificat multi-domaines (SAN)
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
-d monsite.fr \
-d www.monsite.fr \
-d shop.monsite.fr \
-d api.monsite.frEmplacement des certificats
Les certificats générés sont stockés dans /etc/letsencrypt/live/{domaine}/ :
/etc/letsencrypt/live/monsite.fr/
├── README # Instructions d'utilisation
├── cert.pem # Certificat du domaine uniquement
├── chain.pem # Chaîne de certification intermédiaire
├── fullchain.pem # cert.pem + chain.pem (utilisé pour serveurs web)
└── privkey.pem # Clé privée (à protéger impérativement)Configuration serveur web
Configuration Nginx :
ssl_certificate /etc/letsencrypt/live/monsite.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monsite.fr/privkey.pem;Configuration Apache :
SSLCertificateFile /etc/letsencrypt/live/monsite.fr/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/monsite.fr/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/monsite.fr/chain.pemRenouvellement automatique
Configuration du renouvellement
Les certificats Let's Encrypt ont une validité de 90 jours. CertBot peut gérer le renouvellement automatique.
Test de renouvellement
certbot renew --dry-runRenouvellement forcé
certbot renew --cert-name monsite.fr --force-renewalAutomatisation via cron
Créez un cron job pour renouveler automatiquement les certificats :
# Éditer la crontab root
crontab -e
# Ajouter la ligne suivante (exécution tous les jours à 3h du matin)
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"Options de post-processing
Recharger le service web après renouvellement :
certbot renew --post-hook "systemctl reload nginx"Exécuter un script personnalisé :
certbot renew --deploy-hook /usr/local/bin/deploy-cert.shExemple de script de déploiement
Contenu du fichier /usr/local/bin/deploy-cert.sh :
#!/bin/bash
# Script exécuté après chaque renouvellement réussi
RENEWED_DOMAINS="${RENEWED_DOMAINS}"
RENEWED_LINEAGE="${RENEWED_LINEAGE}"
# Recharger les services concernés
if [[ $RENEWED_DOMAINS == *"monsite.fr"* ]]; then
systemctl reload nginx
logger "Certificat monsite.fr renouvelé et Nginx rechargé"
fi
# Copier le certificat vers d'autres serveurs (optionnel)
# scp -r $RENEWED_LINEAGE/ user@backend-server:/etc/letsencrypt/live/Surveillance du renouvellement
Vérification de l'expiration
# Lister les certificats avec dates d'expiration
certbot certificates
# Extraire la date d'expiration d'un certificat
openssl x509 -in /etc/letsencrypt/live/monsite.fr/cert.pem -noout -enddate
# notAfter=May 27 12:00:00 2026 GMT
# Vérifier combien de jours restants
openssl x509 -in /etc/letsencrypt/live/monsite.fr/cert.pem -noout -checkend 2592000
# Certificate will not expire (si > 30 jours)Monitoring via logs
# Logs CertBot
tail -f /var/log/letsencrypt/letsencrypt.log
# Logs hooks SdV
tail -f /var/log/certbot-sdv-scripts.logTroubleshooting
Diagnostic des erreurs courantes
Erreur d'authentification API
Error: API authentication failed (401 Unauthorized)Causes possibles :
- Clé API incorrecte dans
/etc/certbot-sdv-scripts/sdv.ini - Adresse IP source non autorisée (filtrage IP SdV)
- Clé API expirée ou révoquée
Vérifications :
# Tester l'accès API manuellement
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://certmanager-endpoint-dns.sdv.fr/dnsapi/v1/domains
# Vérifier l'IP publique du serveur
curl https://ifconfig.meÉchec validation DNS
Timeout during connect (likely firewall problem)
Challenge validation failedCauses possibles :
- Record TXT non propagé à temps
- Problème de propagation DNS
- TTL trop élevé sur la zone
Vérifications :
# Vérifier la présence du record TXT
dig _acme-challenge.monsite.fr TXT +short
# Interroger les serveurs DNS autoritatifs directement
dig @ns1.sdv.fr _acme-challenge.monsite.fr TXT +short
# Vérifier la propagation DNS mondiale
# https://dnschecker.org/#TXT/_acme-challenge.monsite.frRate limiting Let's Encrypt
Error: too many certificates already issued for: monsite.frLimites Let's Encrypt :
| Type de limite | Valeur | Période |
|---|---|---|
| Certificats par domaine enregistré | 50 | 7 jours |
| Noms par certificat | 100 | - |
| Renouvellements | Illimité | - |
| Échecs de validation | 5 | 1 heure |
| Comptes par IP | 10 | 3 heures |
Solution : Utiliser l'environnement staging pour les tests, ou attendre la fin de la période.
Permissions insuffisantes
Permission denied: '/etc/certbot-sdv-scripts/sdv.ini'Solution :
# Vérifier et corriger les permissions
ls -la /etc/certbot-sdv-scripts/
chown root:root /etc/certbot-sdv-scripts/sdv.ini
chmod 600 /etc/certbot-sdv-scripts/sdv.iniMode debug
Activer le mode debug pour analyser les problèmes :
# Verbose CertBot
certbot certonly -vv \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
--staging \
-d test.monsite.fr
# Debug des scripts SdV
bash -x /etc/certbot-sdv-scripts/authenticator.sh
# Logs détaillés
tail -f /var/log/letsencrypt/letsencrypt.log
tail -f /var/log/certbot-sdv-scripts.logScript de validation d'environnement
Utilisez le script fourni pour valider la configuration :
/etc/certbot-sdv-scripts/check_env.shCe script vérifie :
- Présence de CertBot
- Permissions des fichiers
- Validité du fichier
sdv.ini - Connectivité vers l'API SdV
- Présence des dépendances (curl, jq, openssl)
Bonnes pratiques
Sécurité
Protection de la clé API
- Ne jamais committer
sdv.inidans un repository Git - Utiliser des permissions restrictives (
chmod 600) - Stocker les clés dans un gestionnaire de secrets en production (Vault, AWS Secrets Manager, etc.)
Isolation des clés
- Utiliser des clés API différentes par environnement (prod/preprod/dev)
- Créer des clés spécifiques par domaine si possible
- Renouveler régulièrement les clés API
Principe de moindre privilège
- L'API SdV pour ACME est déjà restreinte aux records TXT
_acme-challenge - Ne pas réutiliser ces clés pour d'autres usages
- Limiter les IP sources au strict nécessaire
Opérationnel
Tests systématiques
- Toujours tester avec
--stagingavant la production - Valider le renouvellement automatique en staging
Monitoring
- Surveiller les dates d'expiration des certificats
- Alerter si renouvellement échoue (logs, métriques)
- Intégrer dans votre système de monitoring (Prometheus, Nagios, etc.)
Documentation
- Maintenir un inventaire des certificats générés
- Documenter la stratégie de renouvellement
- Tracer les changements de configuration
Automatisation
- Préférer le renouvellement automatique via cron
- Utiliser
--deploy-hookpour recharger les services - Intégrer dans votre CI/CD si possible
Architecture
Répartition des certificats
- Certificat wildcard pour simplifier la gestion de nombreux sous-domaines
- Certificats spécifiques pour domaines critiques (séparation des clés privées)
- Certificat multi-domaines pour des services liés
Haute disponibilité
- Synchroniser les certificats entre serveurs (rsync, Ansible, etc.)
- Utiliser un stockage centralisé pour les certificats (NFS, S3)
- Prévoir un mécanisme de basculement en cas d'échec de renouvellement
Gestion multi-environnements
| Environnement | Domaine | Clé API | Serveur CertBot |
|---|---|---|---|
| Production | monsite.fr, *.monsite.fr | prod_api_key | prod-certbot-01 |
| Préproduction | preprod.monsite.fr, *.preprod.monsite.fr | preprod_api_key | preprod-certbot-01 |
| Développement | dev.monsite.fr | dev_api_key | dev-certbot-01 |
Points d'attention
Délais de propagation DNS
- Les records TXT créés par l'API SdV peuvent nécessiter quelques secondes de propagation
- Les scripts SdV intègrent un délai d'attente pour garantir la propagation
- En cas d'échec répété, augmenter le délai dans le script
authenticator.sh
TTL et cache DNS
- Un TTL trop élevé sur la zone peut ralentir la validation
- Les résolveurs DNS peuvent cacher temporairement l'absence du record TXT
- Recommandation : TTL de 60-300 secondes pour les records
_acme-challenge
Renouvellement et indisponibilité
- Le renouvellement ne provoque aucune interruption de service si bien configuré
- Utiliser
--post-hookou--deploy-hookpour recharger les services (pas de restart) - Tester le renouvellement en dehors des heures de production
Certificats wildcard et domaine racine
- Un certificat
*.monsite.frne couvre pasmonsite.fr - Toujours inclure le domaine racine :
-d '*.monsite.fr' -d monsite.fr - Alternative : générer deux certificats séparés
Dépendances externes
- Let's Encrypt : Dépendance critique externe (SLA ~99.9%)
- API SdV : Point de défaillance unique pour validation DNS
- DNS autoritatifs SdV : Doivent être joignables par Let's Encrypt
Mitigation :
- Renouveler les certificats bien avant expiration (30 jours recommandé)
- Conserver des certificats de secours valides
- Mettre en place des alertes d'expiration
Notes d'exploitation
Checklist de mise en production
- CertBot installé et testé
- Scripts SdV installés dans
/etc/certbot-sdv-scripts - Permissions des scripts vérifiées (
root:root,600/700) - Fichier
sdv.iniconfiguré avec clé API valide - Test de génération en staging réussi
- Génération du certificat production validée
- Configuration serveur web mise à jour (Nginx/Apache)
- Renouvellement automatique configuré (cron)
- Test du renouvellement avec
--dry-runréussi - Monitoring de l'expiration mis en place
- Documentation mise à jour (wiki, runbook)
Procédures opérationnelles
Renouvellement manuel
En cas d'échec du renouvellement automatique :
# 1. Vérifier l'état des certificats
certbot certificates
# 2. Identifier le certificat expirant
openssl x509 -in /etc/letsencrypt/live/monsite.fr/cert.pem -noout -dates
# 3. Tenter un renouvellement en mode debug
certbot renew -vv --cert-name monsite.fr
# 4. En cas d'échec persistant, régénérer
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
--force-renewal \
-d monsite.fr
# 5. Recharger le serveur web
systemctl reload nginxRévocation de certificat
Si une clé privée est compromise, révoquer immédiatement le certificat :
# Révoquer le certificat
certbot revoke --cert-path /etc/letsencrypt/live/monsite.fr/cert.pem
# Régénérer un nouveau certificat
certbot certonly \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/certbot-sdv-scripts/authenticator.sh \
--manual-cleanup-hook /etc/certbot-sdv-scripts/cleanup.sh \
-d monsite.fr
# Recharger le serveur web
systemctl reload nginxCommandes utiles
Gestion des certificats
# Lister tous les certificats gérés
certbot certificates
# Détails d'un certificat spécifique
certbot certificates --cert-name monsite.fr
# Supprimer un certificat (sans révoquer)
certbot delete --cert-name monsite.fr
# Tester le renouvellement de tous les certificats
certbot renew --dry-run
# Renouveler uniquement les certificats expirant dans 30 jours
certbot renew
# Renouveler en forçant même si non expiré
certbot renew --force-renewalVérification CertBot
# Vérifier la configuration CertBot
certbot --version
certbot pluginsDebug SSL en production
# Debugger un certificat SSL en production
openssl s_client -connect monsite.fr:443 -servername monsite.fr
# Extraire l'émetteur du certificat en production
echo | openssl s_client -connect monsite.fr:443 -servername monsite.fr 2>/dev/null | openssl x509 -noout -issuerContact et support
En cas de problème ou pour améliorer cette documentation, contactez :
- Support SdV : Outil de ticket
- Issues scripts SdV : https://gitlab.sdv.fr/sdv_public/certbot_challenge_dns_sdv/-/issues
- Documentation Let's Encrypt : https://letsencrypt.org/docs/