Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Guide Lego et Challenge DNS

Introduction

Lego est un client Let's Encrypt et une bibliothèque ACME écrite en Go. Il supporte nativement de nombreux providers DNS, dont PowerDNS, ce qui permet de générer des certificats SSL/TLS via le challenge DNS-01.

Documentation officielle : https://go-acme.github.io/lego/dns/

Avantages de Lego

  • Écrit en Go : binaire statique unique, pas de dépendances runtime
  • Support natif de nombreux providers DNS
  • Performance élevée
  • Idéal pour l'automatisation et l'intégration dans des pipelines CI/CD
  • Compatible avec Docker et Kubernetes

Provider PowerDNS

En utilisant le provider DNS pdns (PowerDNS) de Lego avec l'endpoint SdV https://powerdns-endpoint-dns.sdv.fr/, vous pouvez générer facilement vos certificats SSL.

Installation

Téléchargement du binaire

Linux AMD64
# Télécharger la dernière version
wget https://github.com/go-acme/lego/releases/download/v4.14.2/lego_v4.14.2_linux_amd64.tar.gz
 
# Extraire l'archive
tar -xzf lego_v4.14.2_linux_amd64.tar.gz
 
# Déplacer le binaire dans le PATH
sudo mv lego /usr/local/bin/
 
# Vérifier l'installation
lego --version

Installation via Docker

Terminal
docker pull goacme/lego:latest

Vérification de l'installation

Terminal
lego --version
# lego version 4.14.2 darwin/amd64

Configuration

Variables d'environnement

Lego utilise des variables d'environnement pour la configuration du provider DNS PowerDNS.

Variables requises

VariableDescriptionExemple
PDNS_API_URLURL de l'API PowerDNShttps://powerdns-endpoint-dns.sdv.fr/
PDNS_API_KEYClé d'API PowerDNS SdVXXXXXX...

Variables optionnelles

VariableDescriptionDéfaut
PDNS_TTLTTL des records DNS créés120
PDNS_PROPAGATION_TIMEOUTTemps max d'attente de propagation2m0s
PDNS_POLLING_INTERVALIntervalle de vérification de propagation2s
PDNS_HTTP_TIMEOUTTimeout HTTP vers l'API30s

Configuration des variables

Terminal
export PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/
export PDNS_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Pour une configuration persistante, ajoutez ces variables dans votre fichier de profil :

Terminal
# Ajouter au ~/.bashrc ou ~/.zshrc
echo 'export PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/' >> ~/.bashrc
echo 'export PDNS_API_KEY=XXXXXX...' >> ~/.bashrc
source ~/.bashrc

Obtention de la clé API

Pour obtenir votre clé API PowerDNS, contactez SdV via l'outil de ticket en fournissant :

  • Liste des adresses IP sources autorisées
  • Liste des domaines concernés
  • Environnement (production, préproduction, développement)
  • Contexte d'utilisation

Génération de certificats

Certificat simple

Génération d'un certificat pour un seul domaine :

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     --accept-tos \
     run

Options principales

OptionDescription
--emailEmail de contact pour notifications Let's Encrypt
--dnsProvider DNS à utiliser (pdns pour PowerDNS)
--domainsDomaine(s) pour le certificat
--accept-tosAccepter les conditions d'utilisation Let's Encrypt
runCommande pour générer un nouveau certificat

Certificat multi-domaines (SAN)

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     --domains www.monsite.fr \
     --domains api.monsite.fr \
     --accept-tos \
     run

Certificat wildcard

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains '*.monsite.fr' \
     --domains monsite.fr \
     --accept-tos \
     run

Test en environnement staging

Avant de générer un certificat production, testez avec l'environnement staging de Let's Encrypt :

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains test.monsite.fr \
     --accept-tos \
     --server https://acme-staging-v02.api.letsencrypt.org/directory \
     run

Exemple d'exécution réussie

Terminal
export PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/
export PDNS_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
lego --email admin@monsite.fr --dns pdns --domains keycloak.monsite.fr --accept-tos run
 
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] acme: Obtaining bundled SAN certificate
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/186475346237
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] acme: Could not find solver for: tls-alpn-01
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] acme: Could not find solver for: http-01
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] acme: use dns-01 solver
2022/12/12 18:32:41 [INFO] [keycloak.monsite.fr] acme: Preparing to solve DNS-01
2022/12/12 18:32:50 [INFO] [keycloak.monsite.fr] acme: Trying to solve DNS-01
2022/12/12 18:32:50 [INFO] [keycloak.monsite.fr] acme: Checking DNS record propagation using [208.67.222.222:53 208.67.220.220:53]
2022/12/12 18:32:52 [INFO] Wait for propagation [timeout: 2m0s, interval: 2s]
2022/12/12 18:32:52 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:32:54 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:32:56 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:32:58 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:00 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:02 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:04 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:06 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:08 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:10 [INFO] [keycloak.monsite.fr] acme: Waiting for DNS record propagation.
2022/12/12 18:33:18 [INFO] [keycloak.monsite.fr] The server validated our request
2022/12/12 18:33:18 [INFO] [keycloak.monsite.fr] acme: Cleaning DNS-01 challenge
2022/12/12 18:33:26 [INFO] [keycloak.monsite.fr] acme: Validations succeeded; requesting certificates
2022/12/12 18:33:27 [INFO] [keycloak.monsite.fr] Server responded with a certificate.

Emplacement des certificats

Par défaut, Lego stocke les certificats dans le répertoire .lego du répertoire courant :

Terminal
.lego/
├── accounts/
   └── acme-v02.api.letsencrypt.org/
       └── admin@monsite.fr/
           ├── account.json
           └── keys/
├── certificates/
   ├── monsite.fr.crt         # Certificat
   ├── monsite.fr.key         # Clé privée
   ├── monsite.fr.issuer.crt  # Certificat intermédiaire
   └── monsite.fr.json        # Métadonnées

Personnaliser le chemin

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     --path /etc/lego \
     --accept-tos \
     run

Renouvellement automatique

Renouvellement manuel

Lego gère automatiquement le renouvellement si le certificat expire dans moins de 30 jours :

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     renew

Options de renouvellement

OptionDescription
--daysNombre de jours avant expiration pour renouveler (défaut: 30)
--reuse-keyRéutiliser la clé privée existante
--renew-hookScript à exécuter après renouvellement

Renouvellement avec hook

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     --renew-hook "/usr/local/bin/reload-services.sh" \
     renew

Exemple de script de hook /usr/local/bin/reload-services.sh :

reload-services.sh
#!/bin/bash
# Script exécuté après renouvellement réussi
 
DOMAIN="$LEGO_CERT_DOMAIN"
CERT_PATH="$LEGO_CERT_PATH"
KEY_PATH="$LEGO_CERT_KEY_PATH"
 
# Copier les certificats vers le serveur web
cp "$CERT_PATH" /etc/nginx/ssl/
cp "$KEY_PATH" /etc/nginx/ssl/
 
# Recharger Nginx
systemctl reload nginx
 
logger "Certificat $DOMAIN renouvelé et Nginx rechargé"

Rendre le script exécutable :

Terminal
chmod +x /usr/local/bin/reload-services.sh

Automatisation via cron

Créez un cron job pour renouveler automatiquement les certificats :

Terminal
# Éditer la crontab
crontab -e
 
# Ajouter la ligne suivante (exécution tous les jours à 3h du matin)
0 3 * * * PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/ PDNS_API_KEY=XXXX /usr/local/bin/lego --email admin@monsite.fr --dns pdns --domains monsite.fr --renew-hook /usr/local/bin/reload-services.sh renew >> /var/log/lego-renew.log 2>&1

Automatisation via systemd timer

Créer le service

Fichier /etc/systemd/system/lego-renew.service :

lego-renew.service
[Unit]
Description=Renew Let''s Encrypt certificates using Lego
After=network-online.target
 
[Service]
Type=oneshot
Environment="PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/"
Environment="PDNS_API_KEY=XXXXXX"
ExecStart=/usr/local/bin/lego --email admin@monsite.fr --dns pdns --domains monsite.fr --renew-hook /usr/local/bin/reload-services.sh renew
StandardOutput=journal
StandardError=journal
 
[Install]
WantedBy=multi-user.target

Créer le timer

Fichier /etc/systemd/system/lego-renew.timer :

lego-renew.timer
[Unit]
Description=Daily renewal of Let''s Encrypt certificates
 
[Timer]
OnCalendar=daily
Persistent=true
 
[Install]
WantedBy=timers.target

Activer le timer

Terminal
# Recharger systemd
systemctl daemon-reload
 
# Activer le timer
systemctl enable lego-renew.timer
 
# Démarrer le timer
systemctl start lego-renew.timer
 
# Vérifier le statut
systemctl status lego-renew.timer
systemctl list-timers lego-renew.timer

Utilisation avec Docker

Génération de certificat

Terminal
docker run --rm \
  -v $(pwd)/.lego:/root/.lego \
  -e PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/ \
  -e PDNS_API_KEY=XXXXXX \
  goacme/lego:latest \
  --email admin@monsite.fr \
  --dns pdns \
  --domains monsite.fr \
  --accept-tos \
  run

Renouvellement avec Docker

Terminal
docker run --rm \
  -v $(pwd)/.lego:/root/.lego \
  -e PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/ \
  -e PDNS_API_KEY=XXXXXX \
  goacme/lego:latest \
  --email admin@monsite.fr \
  --dns pdns \
  --domains monsite.fr \
  renew

Docker Compose

Fichier docker-compose.yml :

docker-compose.yml
services:
  lego:
    image: goacme/lego:latest
    volumes:
      - ./lego:/root/.lego
    environment:
      - PDNS_API_URL=https://powerdns-endpoint-dns.sdv.fr/
      - PDNS_API_KEY=${PDNS_API_KEY}
    command: >
      --email admin@monsite.fr
      --dns pdns
      --domains monsite.fr
      --accept-tos
      run

Exécution :

Terminal
# Définir la clé API
export PDNS_API_KEY=XXXXXX
 
# Générer le certificat
docker-compose run --rm lego
 
# Renouveler
docker-compose run --rm lego \
  --email admin@monsite.fr \
  --dns pdns \
  --domains monsite.fr \
  renew

Intégration Kubernetes

ConfigMap pour la configuration

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: lego-config
  namespace: cert-manager
data:
  email: admin@monsite.fr
  pdns-api-url: https://powerdns-endpoint-dns.sdv.fr/

Secret pour la clé API

Terminal
kubectl create secret generic lego-pdns-secret \
  --from-literal=api-key=XXXXXX \
  -n cert-manager

CronJob pour renouvellement

cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: lego-renew
  namespace: cert-manager
spec:
  schedule: "0 3 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: lego
            image: goacme/lego:latest
            args:
            - --email
            - admin@monsite.fr
            - --dns
            - pdns
            - --domains
            - monsite.fr
            - --path
            - /lego
            - renew
            env:
            - name: PDNS_API_URL
              valueFrom:
                configMapKeyRef:
                  name: lego-config
                  key: pdns-api-url
            - name: PDNS_API_KEY
              valueFrom:
                secretKeyRef:
                  name: lego-pdns-secret
                  key: api-key
            volumeMounts:
            - name: lego-data
              mountPath: /lego
          volumes:
          - name: lego-data
            persistentVolumeClaim:
              claimName: lego-pvc
          restartPolicy: OnFailure

Troubleshooting

Erreurs courantes

Erreur d'authentification API

error: failed to create challenge: 401 Unauthorized

Vérifications :

Terminal
# Vérifier les variables d'environnement
echo $PDNS_API_URL
echo $PDNS_API_KEY
 
# Tester l'accès à l'API
curl -H "X-API-Key: $PDNS_API_KEY" "$PDNS_API_URL/api/v1/servers"

Timeout de propagation DNS

error: challenge validation failed: DNS problem: query timed out

Augmenter le timeout de propagation :

Terminal
export PDNS_PROPAGATION_TIMEOUT=5m
export PDNS_POLLING_INTERVAL=5s
 
lego --email admin@monsite.fr --dns pdns --domains monsite.fr run

Certificat déjà existant

error: Certificate already exists for domain

Forcer le renouvellement :

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     renew --days 90

Mode debug

Activer le mode verbose pour diagnostic :

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     --accept-tos \
     run \
     --dns.resolvers 8.8.8.8:53 \
     --http.timeout 60

Vérification DNS manuelle

Terminal
# Vérifier la présence du record TXT
dig _acme-challenge.monsite.fr TXT +short
 
# Interroger les serveurs DNS SdV directement
dig @ns1.sdv.fr _acme-challenge.monsite.fr TXT +short

Bonnes pratiques

Sécurité

Protection de la clé API

  • Ne jamais committer la clé API dans un repository Git
  • Utiliser des variables d'environnement ou un gestionnaire de secrets
  • Limiter les permissions de la clé aux domaines strictement nécessaires
  • Renouveler régulièrement la clé API

Stockage des certificats

  • Protéger les clés privées avec des permissions restrictives (chmod 600)
  • Stocker les certificats dans un emplacement sécurisé
  • Sauvegarder régulièrement les certificats et clés
Terminal
# Sécuriser les permissions
chmod 600 .lego/certificates/*.key
chmod 644 .lego/certificates/*.crt

Opérationnel

Tests en staging

  • Toujours tester avec l'environnement staging avant la production
  • Valider le processus de renouvellement en staging

Monitoring

  • Surveiller les dates d'expiration des certificats
  • Alerter en cas d'échec de renouvellement
  • Logger toutes les opérations

Automatisation

  • Préférer le renouvellement automatique
  • Utiliser des hooks pour déployer automatiquement les certificats
  • Intégrer dans votre CI/CD

Architecture

Gestion multi-environnements

EnvironnementDomaineClé APIServeur
Productionmonsite.fr, *.monsite.frprod_api_keyprod-cert-01
Préproductionpreprod.monsite.frpreprod_api_keypreprod-cert-01
Développementdev.monsite.frdev_api_keydev-cert-01

Haute disponibilité

  • Centraliser le stockage des certificats (NFS, S3, etc.)
  • Synchroniser les certificats entre serveurs
  • Prévoir un mécanisme de fallback

Points d'attention

Différences avec CertBot

  • Lego utilise l'API PowerDNS complète (toutes permissions)
  • CertBot SdV utilise une API restreinte (uniquement records _acme-challenge)
  • Lego est plus adapté à l'automatisation et aux conteneurs
  • CertBot est plus adapté aux installations traditionnelles sur serveur

Permissions PowerDNS

La clé API PowerDNS utilisée par Lego permet de :

  • Créer, modifier et supprimer des records DNS
  • Gérer les zones DNS complètes
  • Modifier la configuration des zones

Implications :

  • Une clé compromise peut impacter l'ensemble de vos zones DNS
  • Utilisez des clés dédiées par environnement
  • Limitez les IP sources autorisées
  • Auditez régulièrement l'utilisation des clés

Rate limiting Let's Encrypt

Les mêmes limites que CertBot s'appliquent :

Type de limiteValeurPériode
Certificats par domaine enregistré507 jours
Noms par certificat100-
Échecs de validation51 heure

Recommandation : Utiliser l'environnement staging pour les tests.

Commandes utiles

Gestion des certificats

Terminal
# Lister les certificats
ls -lh .lego/certificates/
 
# Afficher les détails d'un certificat
openssl x509 -in .lego/certificates/monsite.fr.crt -text -noout
 
# Vérifier la date d'expiration
openssl x509 -in .lego/certificates/monsite.fr.crt -noout -enddate
 
# Vérifier la chaîne de certification
openssl verify -CAfile .lego/certificates/monsite.fr.issuer.crt .lego/certificates/monsite.fr.crt

Test SSL en production

Terminal
# Tester le certificat SSL
openssl s_client -connect monsite.fr:443 -servername monsite.fr
 
# Vérifier l'émetteur
echo | openssl s_client -connect monsite.fr:443 -servername monsite.fr 2>/dev/null | openssl x509 -noout -issuer
 
# Tester avec curl
curl -vI https://monsite.fr

Révocation de certificat

Terminal
lego --email admin@monsite.fr \
     --dns pdns \
     --domains monsite.fr \
     revoke

Contact et support

En cas de problème ou pour améliorer cette documentation, contactez :