Aller au contenu
ecdsa.com

HTTP-01 vs DNS-01 : choisir un challenge ACME

Les deux prouvent à l’autorité de certification que vous contrôlez un nom. L’un passe par le serveur web, l’autre par le DNS, et c’est ce qui détermine quels certificats vous pouvez obtenir et quels identifiants vous devez conserver.

Le choix entre HTTP-01 et DNS-01 est la première décision à prendre pour automatiser des certificats avec ACME (RFC 8555). Avec HTTP-01, l’autorité de certification (AC) récupère un jeton sur votre serveur web via le port 80 ; avec DNS-01, elle interroge un enregistrement TXT de votre zone. Ce sont deux méthodes de validation de domaine au sens des Baseline Requirements, et elles donnent des certificats identiques, mais elles diffèrent par ce qu’elles peuvent valider, par l’endroit où elles peuvent s’exécuter et par ce qui peut mal tourner.

Vue d’ensemble

HTTP-01DNS-01
SpécificationRFC 8555 §8.3 ; Baseline Requirements §3.2.2.4.19RFC 8555 §8.4 ; Baseline Requirements §3.2.2.4.7
Ce que vous prouvezLe contrôle du serveur web qui répond pour le nomLe contrôle de la zone DNS, ou du nom _acme-challenge délégué
Où se trouve la preuvehttp://name/.well-known/acme-challenge/tokenEnregistrement TXT à _acme-challenge.name
ContenuL’autorisation de clé (token.thumbprint)base64url de son condensat SHA-256 (43 caractères)
Noms wildcardNon autorisésAutorisés
Certificats pour adresses IPAutorisés (RFC 8738)Impossibles
Exigence réseauPort TCP 80 entrant ; Let’s Encrypt suit jusqu’à 10 redirections vers les ports 80 ou 443Seuls vos serveurs DNS faisant autorité doivent être joignables
Hôtes internes ou derrière un pare-feuNonOui
Nombreux serveurs ou anycastChaque nœud doit servir le jeton, ou le relayer vers un répondeur uniqueUn enregistrement par nom, indépendant des serveurs
Secrets sur le serveurAucun, au-delà de l’accès en écriture à la racine webIdentifiants d’API DNS (limitez leur portée par délégation CNAME)
Échecs typiquesPort 80 bloqué, boucles de redirection, réponse du CDN ou du WAF, enregistrements AAAA obsolètesPropagation vers les serveurs secondaires, DNSSEC cassé, enregistrements résiduels, limites d’API

Ce que l’AC vérifie réellement

Les deux challenges utilisent une autorisation de clé (key authorization) : le jeton du challenge, suivi d’un point puis de l’empreinte JWK (RFC 7638) de la clé de votre compte ACME. Comme la clé du compte fait partie de la preuve, une personne qui voit le jeton ne peut pas réussir le challenge pour son propre compte. HTTP-01 sert l’autorisation de clé telle quelle ; DNS-01 publie son condensat SHA-256, qui tient dans un enregistrement TXT. Le script ci-dessous reproduit les deux valeurs pour la clé de compte d’exemple de la RFC 7638 et les jetons d’exemple de la RFC 8555 (Node.js 26).

Calculer la réponse HTTP-01 et l’enregistrement DNS-01
import { createHash } from "node:crypto";

// Account public key: the RSA example JWK from RFC 7638 §3.1
const accountJwk = {
  kty: "RSA",
  e: "AQAB",
  n: "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
};

const b64url = (buf) => buf.toString("base64url");
const sha256 = (s) => createHash("sha256").update(s).digest();

// RFC 7638: hash the required members in lexicographic order
const { e, kty, n } = accountJwk;
const thumbprint = b64url(sha256(JSON.stringify({ e, kty, n })));
console.log("account key thumbprint:", thumbprint);

// http-01 (RFC 8555 §8.3): serve the key authorization itself
const httpToken = "LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0";
console.log("\nhttp-01");
console.log(`  GET http://www.example.org/.well-known/acme-challenge/${httpToken}`);
console.log(`  body: ${httpToken}.${thumbprint}`);

// dns-01 (RFC 8555 §8.4): publish base64url(SHA-256(key authorization))
const dnsToken = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA";
const txt = b64url(sha256(`${dnsToken}.${thumbprint}`));
console.log("\ndns-01");
console.log(`  _acme-challenge.www.example.org. 300 IN TXT "${txt}"`);
Sortie
account key thumbprint: NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs

http-01
  GET http://www.example.org/.well-known/acme-challenge/LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0
  body: LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0.NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs

dns-01
  _acme-challenge.www.example.org. 300 IN TXT "ZTRx1Ckl1-tM05o5zaizTTA0yUy5AGereMgSNWC6Ll8"

L’empreinte correspond à la valeur publiée dans la RFC 7638 §3.1, ce qui confirme le calcul. Les clients font tout cela pour vous ; connaître ces valeurs aide quand vous déboguez à la main un challenge qui échoue, avec curl ou dig.

Contrôles multi-perspectives et DNSSEC

Depuis 2025, les AC publiques doivent confirmer chaque validation depuis plusieurs points du réseau (Baseline Requirements §3.2.2.9). Depuis le 15 juin 2026, au moins quatre perspectives distantes y participent, éloignées d’au moins 500 km les unes des autres et réparties dans au moins deux régions de registres Internet régionaux, et une seule peut être en désaccord ; le minimum passe à cinq le 15 décembre 2026. Pour HTTP-01, cela signifie que chaque nœud anycast, chaque réponse GeoDNS et chaque adresse IPv4 ou IPv6 du nom doit servir le jeton. Pour DNS-01, chaque serveur de noms faisant autorité doit déjà avoir l’enregistrement au moment où vous demandez la validation à l’AC.

Depuis le 15 mars 2026, les AC doivent aussi valider DNSSEC lors des requêtes de validation de domaine et des requêtes CAA (vote SC-085v2). Les zones non signées ne sont pas concernées, mais une zone signée dont une signature a expiré ou dont l’enregistrement DS est cassé bloque désormais l’émission pour les deux types de challenge ; l’inspecteur DNSSEC affiche la chaîne que l’AC vérifiera.

Réduire la portée des identifiants DNS

Le principal risque de DNS-01 tient à l’identifiant qu’il exige : un jeton d’API DNS posé sur un serveur web peut souvent réécrire toute la zone. Comme les AC lisent l’enregistrement TXT par une résolution DNS ordinaire, qui suit les délégations CNAME et NS, le nom _acme-challenge peut pointer vers une zone distincte où le serveur a le droit d’écrire, et nulle part ailleurs :

Ne déléguer que le nom du challenge
_acme-challenge.example.com.  3600  IN  CNAME  example-com.acme.example.net.

Des outils comme acme-dns, ou des jetons du fournisseur limités à un enregistrement ou à une zone, restreignent alors ce que permet un identifiant volé. Associez cela à des enregistrements CAA utilisant les paramètres de la RFC 8657, que les AC doivent traiter à partir du 15 mars 2027 :

CAA : une AC, un compte, validation DNS uniquement
example.com.  IN  CAA  0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890; validationmethods=dns-01"
example.com.  IN  CAA  0 issuewild "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890; validationmethods=dns-01"

Avec validationmethods en place, un attaquant qui contrôle brièvement le port 80 ou un chemin web de votre serveur ne peut plus obtenir de certificat via HTTP-01. Le générateur d’enregistrements CAA produit ces enregistrements.

TLS-ALPN-01 et enregistrements DNS persistants

TLS-ALPN-01 (RFC 8737) valide sur le port 443, au sein du handshake TLS, à l’aide du protocole acme-tls/1 et d’un certificat auto-signé qui contient le condensat de l’autorisation de clé. Il convient aux proxys et aux équilibreurs de charge qui terminent TLS là où le port 80 est fermé ; comme HTTP-01, il peut valider des adresses IP, mais pas des wildcards.

DNS-PERSIST-01 supprime la modification DNS à chaque renouvellement. Le vote SC-088v3 (octobre 2025) a ajouté la méthode « DNS TXT Record with Persistent Value » aux Baseline Requirements, en tant que §3.2.2.4.22 : un seul enregistrement TXT de longue durée, à _validation-persist.name, désigne l’AC et l’URI de votre compte ACME, éventuellement avec policy=wildcard. Le challenge ACME n’est encore qu’un brouillon de l’IETF (Internet-Draft). Google Trust Services prend en charge la version 01 de ce brouillon depuis le 28 septembre 2026 ; Let’s Encrypt ne l’a proposé que dans son environnement de test (staging) et, en octobre 2026, attend la résolution d’un problème encore ouvert dans le brouillon pour le proposer en production. La contrepartie : la clé du compte devient une autorisation permanente, protégez-la donc comme un identifiant DNS.

La validation va bientôt avoir lieu à chaque renouvellement

La réutilisation des autorisations diminue avec la durée de vie des certificats. Les Baseline Requirements plafonnent la réutilisation de la validation de domaine à 200 jours aujourd’hui, à 100 jours à partir de mars 2027 et à 10 jours à partir de mars 2029. Le profil par défaut de Let’s Encrypt réutilise les autorisations pendant 30 jours aujourd’hui, 10 jours à partir du 10 février 2027 et 7 heures à partir du 16 février 2028. Quel que soit le challenge choisi, il doit s’exécuter sans intervention ; copier des valeurs TXT à la main ne tiendra pas au-delà de 2028.

Quand choisir l’un ou l’autre

  • Un seul serveur web public, avec le client ACME installé dessus : HTTP-01.
  • Certificats wildcard : DNS-01 (ou DNS-PERSIST-01 là où votre AC le propose).
  • Hôtes internes avec des noms publics, services accessibles uniquement par VPN, environnements de développement : DNS-01 ; n’oubliez pas que les noms apparaîtront dans les journaux CT.
  • Parcs derrière des équilibreurs de charge, déploiements multirégions ou anycast : DNS-01, ou HTTP-01 avec chaque nœud qui relaie /.well-known/acme-challenge/ vers un répondeur unique.
  • CDN et plateformes gérées : laissez la plateforme valider (en général via HTTP-01 sur son réseau de périphérie, ou via un CNAME que vous ajoutez une seule fois).
  • Certificats pour adresses IP : HTTP-01 ou TLS-ALPN-01 ; chez Let’s Encrypt, uniquement dans le profil shortlived de six jours.
  • Port 80 fermé par une politique interne : DNS-01 ou TLS-ALPN-01.

Notes de migration

  1. Passer de HTTP-01 à DNS-01 : créez une zone dédiée aux challenges, faites pointer chaque nom _acme-challenge vers elle par un CNAME, donnez au client ACME un jeton limité à cette zone et changez le type de challenge du client ; les certificats existants continuent de fonctionner.
  2. Vérifiez la propagation avant de répondre au challenge : la plupart des clients peuvent attendre que tous les serveurs faisant autorité renvoient l’enregistrement ; activez cette option plutôt qu’une attente de durée fixe.
  3. Faites le ménage : les clients devraient supprimer les enregistrements TXT après la validation (RFC 8555 §8.4) ; les restes s’accumulent et ralentissent les requêtes DNS.
  4. Verrouillez avec CAA en utilisant accounturi et validationmethods, pour issue comme pour issuewild.
  5. Renouvelez selon le calendrier de l’AC : utilisez ACME Renewal Information (ARI, RFC 9773) là où il est pris en charge, sinon renouvelez aux deux tiers environ de la durée de vie ; le calculateur de durée de vie des certificats affiche les limites selon la date.
  6. Surveillez les émissions dans les journaux CT (Certificate Transparency pour les développeurs), afin de voir les certificats obtenus par n’importe quelle méthode.

Références

Tous les comparatifs