Если ваш сайт под CDN, за ним обратный прокси или балансировщик, «обычный» выпуск сертификата через Let's Encrypt с проверкой http-01 рано или поздно начинает сбоить. Типичные жалобы: «сертификат не продлился ночью», «вчера работало, сегодня 403 на валидации», «IPv6 ушел на CDN и все упало». Решение, проверенное практикой: перейти на dns-01. Ниже разберем, почему http-01 нестабилен за CDN/reverse proxy, как правильно внедрить dns-01, какие подводные камни у TXT-записей и как автоматизировать ротацию SSL без даунтайма.
Как ACME-проверки устроены и что мешает за прокси
Сервисы ACME (в первую очередь Let's Encrypt) предлагают несколько способов доказать владение доменом:
http-01— проверяющий ходит по HTTP наhttp://example.com/.well-known/acme-challenge/<token>и ожидает конкретный ответ. Разрешены 301/302 на HTTPS, но результат должен совпасть.tls-alpn-01— проверяющий стучится на 443 и ожидает специальный ALPN и сертификат-соответствие токену на самом хосте. За TLS-терминацией это почти всегда ломается: виден CDN, а не ваш origin.dns-01— проверяющий читает TXT у_acme-challenge.example.comи сверяет значение. Состояние 80/443 здесь не важно — критичен только DNS.
Когда домен спрятан за CDN или обратным прокси, первые два способа «натыкаются» на чужую терминацию, агрессивный кеш, переписывание локаций и фильтрацию трафика. Именно поэтому dns-01 практически универсален: контроль принадлежности домена осуществляется в DNS.
Почему http-01 нестабилен за CDN и reverse proxy
В бою мы видим повторяющийся набор проблем, из-за которых автоматическое продление рвется в самый неподходящий момент:
- Порт 80 закрыт на периметре. Для
http-01это фатально: валидатор обязан достучаться до HTTP. - Принудительный редирект на HTTPS, а на 443 висит CDN c нестандартными правилами. Формально редирект допустим, но дальше прилетает не тот контент.
- WAF/CDN режут запросы по User-Agent или rate limit. Проверка получает 403/429.
- Кеширование и оптимизации CDN:
/.well-known/acme-challenge/могут минифицировать, сжимать, менять заголовки — хеш не сходится. - Несогласованность A/AAAA. Есть AAAA на CDN и A на origin; валидатор предпочел IPv6 и уперся не туда.
- Базовая авторизация, IP-алловлист и VPN. Валидатор упирается в 401/403 или не входит в разрешенный список.
- Неверная маршрутизация в прокси. Нет явного
locationдля/.well-known— запрос уходит в приложение и получает 404/405. - Мульти-CDN и канареечные релизы. В одном регионе новая конфигурация пропускает валидацию, в другом старая — режет.
Все это может работать «месяцами», а затем внезапно сломаться после невинного изменения в конфигурации CDN, правил кеша или порядка listen-директив. В продакшене так жить нельзя.

Костыли для http-01 и почему их лучше избегать
Да, можно попытаться подружить проверку с инфраструктурой: открыть 80, прописать исключение для /.well-known/acme-challenge/, отключить кеш и WAF на этой папке, поднять отдельный виртуальный хост только ради челенджа. Это работает, но сопровождается большим количеством допущений и точек отказа. Чем сложнее периметр, тем выше шанс, что очередной редирект или IPv6-переключение снова сломают продление.
Если все же идете этим путем, добавьте явный location в прокси, который минует фильтры и кеши, отдает файл из webroot и не делает редиректов. Пример для Nginx (минимальный скелет):
server {
listen 80;
server_name example.com www.example.com;
location ^~ /.well-known/acme-challenge/ {
default_type text/plain;
root /var/www/letsencrypt;
add_header Cache-Control no-store;
}
location / {
return 301 https://$host$request_uri;
}
}
Однако даже при таком упрощенном сервере вы зависите от внешнего CDN, который может перехватывать 80 или менять поведение по регионам. Для устойчивого продакшена лучше перейти на dns-01.
Почему dns-01 выигрывает
dns-01 подтверждает владение доменом через TXT-запись в зоне: ACME-валидатор читает _acme-challenge.example.com и сверяет значение с ожиданием. Преимущества:
- Независимость от HTTP и TLS-терминации. Хоть полностью выключите сайт — продление пройдет.
- Работает за любыми CDN, балансировщиками и прокси.
- Поддерживает wildcard-сертификаты (
*.example.com), которыеhttp-01не выпускает. См. подробное руководство Wildcard SSL через DNS‑01: полная автоматизация. - Удобная автоматизация через API DNS-провайдера или RFC 2136 для собственного DNS.
Главная тонкость — корректно и безопасно автоматизировать создание и удаление TXT-записей и учесть задержки распространения DNS.
Переход на dns-01: стратегия миграции
Рекомендуем не выключать текущую схему до первого успешного выпуска через dns-01. Типовой план:
- Подготовьте ACME-клиент (или плагин) для
dns-01в staging-окружении, чтобы не поймать лимиты. - Настройте доступ к API вашего DNS с минимальными правами: только редактирование TXT в нужной зоне.
- Сделайте тестовый выпуск для одного поддомена, проверьте корректность TTL и время распространения.
- Переведите основной домен на
dns-01, проверьте автопродление и перезагрузку веб-сервера без даунтайма. - Опционально: добавьте wildcard и объедините SAN-наборы (апекс и
www) в один заказ сертификата. О лимитах и SAN см. ограничения Let's Encrypt и автоматизация.
Certbot: плагин для DNS
Certbot поддерживает множество DNS-плагинов. Принцип одинаков: вы кладете учетные данные API в конфиг с правами 0600 и вызываете certbot с провайдером, указывая домены. Дальше certbot сам создаст TXT, подождет распространения, подтвердит и удалит запись. Базовая схема команд:
# Установка плагина под вашего DNS-провайдера (пример: certbot-dns-xyz)
# Первый выпуск в staging (без рисков по лимитам)
certbot certonly --dns-xyz --dns-xyz-credentials /etc/letsencrypt/dns-xyz.ini --server https://acme-staging-v02.api.letsencrypt.org/directory -d example.com -d www.example.com
# Продакшн выпуск, при необходимости с wildcard
certbot certonly --dns-xyz --dns-xyz-credentials /etc/letsencrypt/dns-xyz.ini -d example.com -d www.example.com -d *.example.com
# Хук на перезагрузку веб-сервера при продлении
certbot renew --deploy-hook "nginx -t && nginx -s reload"
У разных провайдеров есть опции ожидания распространения (sleep). Для нестабильных зон разумно закладывать 60–120 секунд и проверять авторитативные NS.
acme.sh: легкий и гибкий клиент
acme.sh удобен большим количеством встроенных DNS-интеграций и простыми деплой-хуками. Общий подход:
# Установка в домашний каталог
curl -s https://get.acme.sh | sh
# Переключение на Let's Encrypt (если нужно)
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
# Экспорт переменных окружения с токеном API провайдера
export XYZ_OAUTH_TOKEN="..."
# Выпуск через DNS, SAN + wildcard
~/.acme.sh/acme.sh --issue --dns dns_xyz -d example.com -d www.example.com -d *.example.com
# Установка сертификатов и перезагрузка Nginx
~/.acme.sh/acme.sh --install-cert -d example.com --key-file /etc/ssl/private/example.com.key --fullchain-file /etc/ssl/certs/example.com.fullchain.pem --reloadcmd "nginx -t && nginx -s reload"
Для зон с медленным DNS предусмотрена опция ожидания --dnssleep, а для сложных сценариев — делегирование CNAME: указываете _acme-challenge.example.com на специальный поддомен, которым управляет отдельный технический аккаунт.
Другие клиенты: lego, dehydrated
lego и dehydrated также поддерживают dns-01 и многочисленные DNS-провайдеры. Принципы одинаковы: храните токены отдельно, используйте staging при отладке, закладывайте паузу на распространение и добавляйте хук на перезагрузку веб-сервиса.
DNS-провайдер и права доступа
Чтобы автоматизация была безопасной, принцип минимальных прав обязателен: токен должен позволять менять только TXT в одной зоне (или даже только под _acme-challenge). Храните учетные данные в файле с правами 0600, следите за журналами действий. Для собственного DNS (Bind/PowerDNS) подходит RFC 2136: выпускаете TSIG-ключ, разрешаете обновления только с нужного IP и имени ключа.
Если TTL у зоны большой (например, 3600), задайте меньший TTL для _acme-challenge или делегируйте поддомен на быстрый DNS. Популярная практика — завести _acme-challenge.example.com как CNAME на _acme-challenge.acme.example.net, которым управляет автоматизация.
Тонкости dns-01 в продакшене
- Несколько значений TXT одновременно. Для SAN-заказов валидатор может требовать несколько значений под одним именем. Не удаляйте предыдущие до завершения всех проверок.
- Wildcard и апекс вместе.
_acme-challenge.example.comиспользуется и дляexample.com, и для*.example.com— значения должны сосуществовать. - Кавычки и длина. Некоторые панели отображают TXT в кавычках или разбивают на части — это нормально, лишь бы итоговая строка совпала. Не вставляйте лишние пробелы.
- Негативный кеш. NXDOMAIN по TXT может закешироваться у рекурсивного резолвера. Проверяйте авторитативные NS и закладывайте паузу.
- Окно проверки ACME. После создания TXT у вас ограниченное время на подтверждение. Клиенты обычно сами дергают
challenge, но не растягивайте процесс. - Удаление TXT после успеха. Это безопасно и полезно, чтобы не скапливать старые значения.
- Staging перед продакшеном. Сначала обкатайте
dns-01на тестовой директории ACME, чтобы не упереться в лимиты.
Автоматизация ротации сертификатов
Как только выпуск освоен, настройте безостановочную ротацию:
- Планировщик. Для certbot —
systemd timerили cron дважды в день; дляacme.sh— встроенный cron при установке. - Проверка конфигурации перед перегрузкой. Для Nginx делайте
nginx -tи только затемnginx -s reload. Для Apache —apachectl configtestиgraceful. - Многосерверные инсталляции. Выпускать можно на одном узле и распространять ключи и цепочки на остальные через безопасный канал (rsync/scp с ограниченными ключами, агенты конфигурации). Следите за правами: приватный ключ не должен быть мирово читаемым.
- Мониторинг срока действия. Алерты за 30/14/7 дней до истечения позволят отловить неожиданные сбои DNS-автоматизации.

Безопасность: токены и ключи
Храните токены DNS-провайдера как секреты: отдельный файл с правами 0600, владелец — пользователь, под которым работает ACME-клиент. Разделите окружения: в staging используйте отдельные токены. Ограничьте исходящие подключения хоста-выпускателя, чтобы он мог обращаться только к API провайдера и ACME-директории. Логи клиентов могут содержать отладочную информацию — не пишите в них токены.
Приватные ключи сертификатов — самый чувствительный артефакт. Раздавайте их только на те серверы, где они действительно нужны, и не копируйте в CI-агенты без крайней необходимости. Если у вас выделенная TLS-терминация, ограничьте распространение ключей только на этот периметр. Если не хотите возиться с ACME или нужен расширенный выпуск, рассмотрите коммерческие SSL-сертификаты.
Чек-лист миграции с http-01 на dns-01
- Выберите ACME-клиент и DNS-интеграцию, подготовьте staging.
- Создайте токен с минимальными правами, положите его в файл 0600.
- Сделайте тестовый выпуск одного домена, проверьте время распространения TXT.
- Настройте хук на перезагрузку веб-сервера с проверкой конфигурации.
- Переведите боевые сертификаты, включите мониторинг срока действия.
- Опционально: настройте CNAME-делегирование для
_acme-challengeи отдельный быстрый DNS.
FAQ: частые вопросы
Можно ли остаться на tls-alpn-01 за CDN? В редких случаях — да, если вы контролируете конечную TLS-терминацию, она принимает ALPN-валидатор и пропускает нужный SNI на ваш хост. С публичными CDN почти всегда нет.
Что с IPv6? Для http-01 малейшая асимметрия между A и AAAA приводит к флаку. dns-01 полностью независим от IP-стека.
Нужно ли держать 80 открытым при dns-01? Нет. Проверки идут через DNS, порт 80 можно закрыть.
Как быть с большим TTL? Используйте отдельный поддомен под _acme-challenge и делегируйте его на DNS с коротким TTL (например, 60). Или увеличьте задержку ожидания в клиенте.
Wildcard и SAN вместе? Да, объединяйте в один заказ: example.com и *.example.com. Следите за тем, чтобы клиент создавал все необходимые TXT одновременно.
Итоги
За CDN и обратными прокси проверка http-01 — постоянный источник сюрпризов: от редиректов и кеша до IPv6 и WAF. Переход на dns-01 снимает зависимость от периметра, позволяет выпускать wildcard и делает продление предсказуемым. Важно грамотно автоматизировать работу с TXT-записями, обкатать процесс в staging, учесть задержки распространения и корректно перезагружать сервисы. После этого ротация сертификатов становится скучной рутиной — как и должно быть в продакшене.


