Перейти к содержимому
ecdsa.com

HTTP-01 или DNS-01: какой тип проверки ACME выбрать

Обе проверки доказывают центру сертификации, что вы контролируете имя. Одна делает это через веб-сервер, другая — через DNS, и от этого зависит, какие сертификаты вы сможете получить и какие учётные данные вам придётся хранить.

Выбор между HTTP-01 и DNS-01 — первое решение, которое приходится принимать при автоматизации выпуска сертификатов через ACME (RFC 8555). При проверке HTTP-01 центр сертификации (certificate authority, CA) забирает токен с вашего веб-сервера по порту 80; при DNS-01 он запрашивает TXT-запись в вашей зоне. Оба типа проверки — методы проверки владения доменом по Базовым требованиям (Baseline Requirements), и оба дают одинаковые сертификаты, но различаются тем, что с их помощью можно подтвердить, где они могут работать и что может пойти не так.

Коротко о главном

HTTP-01DNS-01
СпецификацияRFC 8555, § 8.3; Базовые требования, § 3.2.2.4.19RFC 8555, § 8.4; Базовые требования, § 3.2.2.4.7
Что вы доказываетеКонтроль над веб-сервером, который отвечает на запросы к этому имениКонтроль над зоной DNS или над делегированным именем _acme-challenge
Где размещается подтверждениеhttp://name/.well-known/acme-challenge/tokenTXT-запись по имени _acme-challenge.name
СодержимоеАвторизация ключа (token.thumbprint)base64url от её дайджеста SHA-256 (43 символа)
Wildcard-именаНе допускаютсяДопускаются
Сертификаты для IP-адресовДопускаются (RFC 8738)Невозможны
Требования к сетиВходящий TCP-порт 80; Let's Encrypt следует не более чем по 10 перенаправлениям на порты 80 или 443Доступны должны быть только ваши авторитетные DNS-серверы
Внутренние хосты или хосты за межсетевым экраномНетДа
Много серверов или anycastКаждый узел должен отдавать токен или проксировать запрос на один отвечающий узелОдна запись на имя, независимо от серверов
Секреты на сервереНичего, кроме права записи в корневой каталог сайтаУчётные данные DNS API (ограничьте их права делегированием через CNAME)
Типичные сбоиЗаблокированный порт 80, циклы перенаправлений, ответ CDN или WAF вместо сервера, устаревшие записи AAAAЗапаздывание распространения на вторичные серверы, сломанный DNSSEC, оставшиеся записи, лимиты API

Что на самом деле проверяет CA

Обе проверки используют авторизацию ключа (key authorization): токен проверки, соединённый точкой с отпечатком JWK (RFC 7638) ключа вашего аккаунта ACME. Поскольку ключ аккаунта входит в подтверждение, тот, кто увидел токен, не сможет пройти проверку для своего аккаунта. HTTP-01 отдаёт авторизацию ключа как есть; DNS-01 публикует её дайджест SHA-256, который помещается в TXT-запись. Скрипт ниже воспроизводит оба значения для примера ключа аккаунта из RFC 7638 и примеров токенов из RFC 8555 (Node.js 26).

Вычисление ответа HTTP-01 и записи 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}"`);
Результат
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"

Отпечаток совпадает со значением, опубликованным в RFC 7638, § 3.1, а значит, вычисление верно. Клиенты делают всё это за вас, но знание этих значений помогает, когда вы вручную отлаживаете непроходящую проверку с помощью curl или dig.

Проверка из нескольких точек сети и DNSSEC

С 2025 года публичные CA обязаны подтверждать каждую проверку из нескольких точек сети (Базовые требования, § 3.2.2.9). С 15 июня 2026 года в проверке участвуют не менее 4 удалённых точек (perspectives), расположенных не ближе 500 км друг от друга и не менее чем в 2 регионах разных региональных интернет-регистраторов (RIR), и не согласиться с остальными может не более одной; 15 декабря 2026 года минимум вырастет до 5. Для HTTP-01 это значит, что каждый узел anycast, каждый вариант ответа GeoDNS и каждый IPv4- или IPv6-адрес этого имени должны отдавать токен. Для DNS-01 к моменту, когда вы просите CA провести проверку, запись уже должна быть на каждом авторитетном DNS-сервере.

С 15 марта 2026 года CA также обязаны проверять DNSSEC при DNS-запросах для проверки владения доменом и для поиска записей CAA (бюллетень SC-085v2). На неподписанные зоны это не влияет, но подписанная зона с истёкшей подписью или сломанной записью DS теперь блокирует выпуск при обоих типах проверки; инспектор DNSSEC показывает цепочку, которую будет проверять CA.

Минимальные права для учётных данных DNS

Главный риск DNS-01 — учётные данные, которые ему нужны: токен DNS API на веб-сервере часто позволяет переписать всю зону. Поскольку CA ищут TXT-запись обычным разрешением имён DNS, которое следует делегированию через CNAME и NS, имя _acme-challenge можно направить в отдельную зону и разрешить серверу запись только в неё:

Делегирование только имени для проверки
_acme-challenge.example.com.  3600  IN  CNAME  example-com.acme.example.net.

Тогда такие инструменты, как acme-dns, или токены провайдера, ограниченные одной записью или одной зоной, сужают возможности украденных учётных данных. Дополните это записями CAA с параметрами из RFC 8657, которые CA обязаны обрабатывать с 15 марта 2027 года:

CAA: один CA, один аккаунт, только проверка через DNS
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"

Когда задан validationmethods, атакующий, который ненадолго получил контроль над портом 80 или веб-путём на вашем сервере, уже не сможет получить сертификат через HTTP-01. Генератор записей CAA составляет такие записи.

TLS-ALPN-01 и постоянные DNS-записи

TLS-ALPN-01 (RFC 8737) проводит проверку на порту 443 внутри TLS-рукопожатия: используются протокол acme-tls/1 и самоподписанный сертификат, содержащий дайджест авторизации ключа. Этот метод подходит для прокси и балансировщиков нагрузки, которые терминируют TLS, когда порт 80 закрыт; как и HTTP-01, он позволяет проверять IP-адреса, но не wildcard-имена.

DNS-PERSIST-01 избавляет от изменения DNS при каждом продлении. Бюллетень SC-088v3 (октябрь 2025 года) добавил метод «DNS TXT Record with Persistent Value» в Базовые требования как § 3.2.2.4.22: одна долгоживущая TXT-запись по имени _validation-persist.name указывает CA и URI вашего аккаунта ACME, при необходимости с policy=wildcard. Сам тип проверки ACME пока остаётся черновиком IETF. Google Trust Services поддерживает черновик 01 с 28 сентября 2026 года; Let's Encrypt предлагает его только в тестовой среде (staging) и, по состоянию на октябрь 2026 года, не запускает в продакшене, пока не решён открытый вопрос в черновике. Обратная сторона: ключ аккаунта превращается в постоянную авторизацию, поэтому защищайте его так же, как учётные данные DNS.

Скоро проверка будет проходить при каждом продлении

Срок повторного использования авторизаций сокращается вместе со сроками действия сертификатов. Базовые требования ограничивают повторное использование результатов проверки владения доменом 200 днями сейчас, 100 днями с марта 2027 года и 10 днями с марта 2029 года. Профиль Let's Encrypt по умолчанию сегодня повторно использует авторизации в течение 30 дней, с 10 февраля 2027 года — 10 дней, а с 16 февраля 2028 года — 7 часов. Какой бы тип проверки вы ни выбрали, он должен работать без участия человека: копирование значений TXT вручную не переживёт 2028 год.

Что когда выбирать

  • Один публичный веб-сервер, на котором работает ACME-клиент: HTTP-01.
  • Wildcard-сертификаты: DNS-01 (или DNS-PERSIST-01, если ваш CA его предлагает).
  • Внутренние хосты с публичными именами, сервисы, доступные только через VPN, среды разработки: DNS-01; помните, что имена попадут в журналы CT.
  • Парки серверов за балансировщиком нагрузки, развёртывания в нескольких регионах или с anycast: DNS-01 или HTTP-01, при котором каждый узел проксирует /.well-known/acme-challenge/ на один отвечающий узел.
  • CDN и управляемые платформы: доверьте проверку платформе (обычно это HTTP-01 через её пограничные узлы или запись CNAME, которую вы добавляете один раз).
  • Сертификаты для IP-адресов: HTTP-01 или TLS-ALPN-01; в Let's Encrypt — только в профиле shortlived со сроком действия 6 дней.
  • Порт 80 закрыт политикой: DNS-01 или TLS-ALPN-01.

Заметки о миграции

  1. Переход с HTTP-01 на DNS-01: создайте отдельную зону для проверок, направьте в неё каждое имя _acme-challenge записью CNAME, выдайте ACME-клиенту токен, ограниченный этой зоной, и переключите тип проверки в клиенте; существующие сертификаты продолжат работать.
  2. Дождитесь распространения записи, прежде чем отвечать на проверку: большинство клиентов умеют ждать, пока все авторитетные серверы не начнут возвращать запись; включите это ожидание вместо фиксированной паузы.
  3. Убирайте за собой: клиентам следует удалять TXT-записи после проверки (RFC 8555, § 8.4); оставшиеся записи накапливаются и замедляют поиск.
  4. Закрепите настройки записями CAA с accounturi и validationmethods — и для issue, и для issuewild.
  5. Продлевайте сертификаты по расписанию CA: где это поддерживается, используйте ACME Renewal Information (ARI, RFC 9773), а иначе продлевайте примерно по истечении двух третей срока действия; калькулятор сроков действия сертификатов показывает ограничения по датам.
  6. Отслеживайте выпуск сертификатов в журналах прозрачности сертификатов (Certificate Transparency для разработчиков), чтобы видеть сертификаты, полученные любым методом.

Источники

Все сравнения