Présentation
Le protocole ACME (utilisé par Let's Encrypt et d’autres autorités de certification) prend en charge le défi DNS-01 pour la validation de domaine. DNS-01 est le seul type de défi qui prend en charge les certificats wildcard (*.example.com), et il ne nécessite pas de serveur HTTP sur la machine cible.
NexDNS propose des intégrations natives avec les clients ACME courants, ainsi qu’un hook CLI générique pour tout client prenant en charge les hooks DNS manuels.
Toutes les intégrations ACME nécessitent un token API, disponible à partir du plan Pro. Chaque client recherche la zone avant d’écrire le défi : le token doit donc porter
zones.readen plus derecords.readetrecords.write. Créez-en un sur nexdns.tech/settings/api-keys.
Comment un certificat wildcard est validé
Le défi est un enregistrement TXT placé à _acme-challenge sous le nom en cours de validation. Un certificat couvrant à la fois example.com et *.example.com produit deux valeurs de défi différentes sous le même nom, et les deux doivent être présentes simultanément – toutes les intégrations ci-dessous le gèrent, raison pour laquelle il ne faut jamais supprimer l’ensemble d’enregistrements entre les deux validations.
Laisser le temps à la propagation
Un enregistrement de challenge met environ 30 secondes à atteindre les serveurs de noms : attendre 30 secondes ne laisse donc aucune marge - nous en avons vu un échouer avec NXDOMAIN. Laissez à l’autorité de certification au moins 60 secondes : le plugin certbot et lego attendent 60 par défaut, et pour acme.sh et le hook CLI, le délai vous appartient.
acme.sh
acme.sh est un client ACME entièrement en shell. Notre hook DNS ne fait pas encore partie d’une version d’acme.sh : placez-le dans ~/.acme.sh/dnsapi/ avant la première exécution avec curl -fsSL https://get.nexdns.tech/acme/dns_nexdns.sh -o ~/.acme.sh/dnsapi/dns_nexdns.sh. Le même fichier se trouve dans le dépôt CLI si vous préférez le lire d’abord.
Émettre un certificat
export NEXDNS_Token="nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
acme.sh --issue --server letsencrypt --dns dns_nexdns \
--dnssleep 60 \
-d example.com -d '*.example.com'
Le token est enregistré dans ~/.acme.sh/account.conf après la première exécution, vous n’avez donc pas besoin de l’exporter à nouveau pour les renouvellements.
Renouveler
Les renouvellements se font automatiquement via cron. Pour forcer un renouvellement manuel :
acme.sh --renew -d example.com
Client lego / Traefik
lego est un client ACME écrit en Go, qui alimente aussi la gestion automatique des certificats de Traefik. Le provider est inclus dans lego à partir de la v5.4.0.
Utilisation autonome
NEXDNS_API_TOKEN=nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
NEXDNS_PROPAGATION_TIMEOUT=300 \
lego --dns nexdns \
--domains example.com \
--domains '*.example.com' \
--email admin@example.com \
--accept-tos \
run
lego lit ses délais comme un simple nombre de secondes : NEXDNS_PROPAGATION_TIMEOUT=300 fonctionne, tandis que 300s échoue à l’analyse et est remplacé sans avertissement par la valeur par défaut de 60 secondes.
Configuration Traefik
Traefik embarque la table des providers de lego à la compilation et utilise encore une version antérieure : il faut donc ici un Traefik compilé avec lego v5.4.0. Ajoutez le resolver de challenge DNS NexDNS à votre configuration Traefik - le docker-compose.yml suivant montre une installation typique :
services:
traefik:
image: traefik:v3 # lego >= v5.4.0
command:
- "--certificatesresolvers.nexdns.acme.dnschallenge=true"
- "--certificatesresolvers.nexdns.acme.dnschallenge.provider=nexdns"
- "--certificatesresolvers.nexdns.acme.email=admin@example.com"
- "--certificatesresolvers.nexdns.acme.storage=/letsencrypt/acme.json"
environment:
NEXDNS_API_TOKEN: "nxd_xxxxxxxxxxxxxxxxxxxx"
volumes:
- letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "443:443"
volumes:
letsencrypt:
Puis utilisez le résolveur dans les labels de votre service :
labels:
- "traefik.http.routers.myapp.tls.certresolver=nexdns"
- "traefik.http.routers.myapp.tls.domains[0].main=example.com"
- "traefik.http.routers.myapp.tls.domains[0].sans=*.example.com"
Client certbot
certbot est le client officiel Let's Encrypt. Utilisez le plugin d’authentification DNS NexDNS pour la validation DNS-01 automatisée.
Installer le plugin
Installez le plugin depuis PyPI, ou utilisez l’image Docker ci-dessous, qui l’intègre déjà.
pip install certbot-dns-nexdns
Créer le fichier d’identifiants
Créez ~/.nexdns/certbot-credentials.ini avec votre token API :
dns_nexdns_token = nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Restreignez les permissions du fichier :
chmod 600 ~/.nexdns/certbot-credentials.ini
Émettre un certificat
certbot certonly \
--authenticator dns-nexdns \
--dns-nexdns-credentials ~/.nexdns/certbot-credentials.ini \
-d example.com \
-d '*.example.com'
Utilisation avec Docker
docker run --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v ~/.nexdns/certbot-credentials.ini:/credentials.ini:ro \
nexdns/certbot certonly \
--non-interactive --agree-tos --email admin@example.com \
--authenticator dns-nexdns \
--dns-nexdns-credentials /credentials.ini \
-d example.com \
-d '*.example.com'
Hook CLI
Si votre client ACME prend en charge les hooks DNS manuels, vous pouvez utiliser le CLI NexDNS comme script de hook. Cela fonctionne avec tout client fournissant les options --manual-auth-hook et --manual-cleanup-hook (ex. : certbot en mode manuel).
certbot avec le hook CLI
certbot certonly --manual --preferred-challenges dns \
--manual-auth-hook "nexdns acme hook --action create && sleep 60" \
--manual-cleanup-hook "nexdns acme hook --action delete" \
-d example.com \
-d '*.example.com'
Le hook lit les variables d’environnement CERTBOT_DOMAIN et CERTBOT_VALIDATION définies par certbot et crée ou supprime automatiquement l’enregistrement TXT _acme-challenge.
Le CLI doit être authentifié avant d’utiliser les hooks. Exécutez
nexdns auth token nxd_xxxou définissez la variable d’environnementNEXDNS_TOKEN.