Le challenge DNS-01 prouve que vous contrôlez un domaine grâce à un enregistrement TXT plutôt qu'à une page web. C'est le seul moyen d'obtenir un certificat wildcard, et il fonctionne pour les serveurs inaccessibles depuis Internet. Ce hook permet à certbot de publier cet enregistrement via l'API NameOcean.
POST /ssl/example.com). Utilisez ce guide lorsque votre serveur doit obtenir et renouveler son propre certificat.dns:read et dns:write. Limitez-la si possible à l'adresse IP du serveur.# curl -fsSL https://nameocean.net/install.sh | sh # curl -fsSL https://nameocean.net/developers/guides/letsencrypt-dns-01/nameocean-hook.sh \ -o /etc/letsencrypt/nameocean-hook.sh # chmod 700 /etc/letsencrypt/nameocean-hook.sh # echo 'NAMEOCEAN_API_KEY=no_live_…' > /etc/letsencrypt/nameocean.env # chmod 600 /etc/letsencrypt/nameocean.env
La clé reste dans un fichier lisible uniquement par root ; les paramètres de renouvellement enregistrés par certbot ne la contiennent jamais.
# certbot certonly --manual --preferred-challenges dns \
--manual-auth-hook "/etc/letsencrypt/nameocean-hook.sh auth" \
--manual-cleanup-hook "/etc/letsencrypt/nameocean-hook.sh cleanup" \
-d example.com -d "*.example.com"
Pour chaque nom, le hook trouve la zone correspondante parmi vos zones NameOcean, ajoute _acme-challenge comme enregistrement TXT et attend que les quatre serveurs de noms le renvoient, généralement en moins de dix secondes. Après la vérification, l'étape de nettoyage supprime exactement l'enregistrement ajouté. example.com et *.example.com utilisent tous deux _acme-challenge.example.com ; les deux valeurs sont publiées côte à côte.
certbot enregistre les hooks avec le certificat, son timer le renouvelle donc de la même manière. Testez-le une fois :
# certbot renew --dry-run
Chaque enregistrement ajouté ou supprimé par le hook apparaît dans Tableau de bord → Activité avec la clé utilisée, et déclenche les événements webhook dns.record.created et dns.record.deleted.
Lisez-le avant de l'exécuter en tant que root. Il appelle uniquement la CLI nameocean et dig.
#!/bin/sh
# certbot DNS-01 hooks for NameOcean DNS:
# --manual-auth-hook "/etc/letsencrypt/nameocean-hook.sh auth"
# --manual-cleanup-hook "/etc/letsencrypt/nameocean-hook.sh cleanup"
# Needs the nameocean CLI and an API key with dns:write, in /etc/letsencrypt/nameocean.env:
# NAMEOCEAN_API_KEY=no_live_...
set -e
[ -f /etc/letsencrypt/nameocean.env ] && . /etc/letsencrypt/nameocean.env && export NAMEOCEAN_API_KEY
# the zone CERTBOT_DOMAIN is in: the longest of your zones it ends with
zone="$NAMEOCEAN_ZONE"
if [ -z "$zone" ]; then
for z in $(nameocean dns ls --json | sed -n 's/.*"name": *"\([^"]*\)".*/\1/p'); do
case "$CERTBOT_DOMAIN" in "$z" | *".$z") [ ${#z} -gt ${#zone} ] && zone="$z" ;; esac
done
fi
[ -n "$zone" ] || { echo "no NameOcean DNS zone for $CERTBOT_DOMAIN" >&2; exit 1; }
name="_acme-challenge"
[ "$CERTBOT_DOMAIN" = "$zone" ] || name="_acme-challenge.${CERTBOT_DOMAIN%.$zone}"
case "$1" in
auth)
id=$(nameocean dns add "$zone" TXT "$name" "$CERTBOT_VALIDATION" --ttl 5m --json \
| sed -n 's/.*"id": *\([0-9][0-9]*\).*/\1/p' | head -n 1)
[ -n "$id" ] || { echo "could not add the TXT record" >&2; exit 1; }
echo "$id" # certbot passes this to the cleanup hook as CERTBOT_AUTH_OUTPUT
# wait until all four nameservers answer with it (usually a few seconds)
for i in $(seq 1 60); do
n=0
for ns in ns1 ns2 ns3 ns4; do
dig +short TXT "$name.$zone" "@$ns.nameocean.net" | grep -q -- "$CERTBOT_VALIDATION" && n=$((n + 1))
done
[ "$n" -eq 4 ] && exit 0
sleep 2
done
echo "the TXT record is not on every nameserver after 2 minutes" >&2
exit 1
;;
cleanup)
[ -z "$CERTBOT_AUTH_OUTPUT" ] || nameocean dns rm "$zone" TXT "$CERTBOT_AUTH_OUTPUT"
;;
*)
echo "usage: $0 auth|cleanup" >&2
exit 2
;;
esac
Le hook effectue deux appels API que vous pouvez reproduire depuis n'importe quel client ACME ou langage :
$ curl -X POST https://nameocean.net/api/v1/dns/example.com/records \ -H "Authorization: Bearer $NAMEOCEAN_API_KEY" -H "Content-Type: application/json" \ -d '{"type": "TXT", "hostname": "_acme-challenge", "text": "<validation>", "ttl": "5m"}' {"id": 4190, "type": "TXT", "hostname": "_acme-challenge", …} $ curl -X DELETE https://nameocean.net/api/v1/dns/example.com/records/TXT/4190 \ -H "Authorization: Bearer $NAMEOCEAN_API_KEY"