DNS-01 — самый удобный способ получить сертификат Let’s Encrypt для доменов, которые не всегда доступны по HTTP (внутренние панели, закрытые стенды, сервисы за VPN), а также для wildcard-сертификатов вида *.example.com. В связке с Cloudflare всё обычно сводится к одному: Certbot автоматически создаёт временную TXT-запись через API и подтверждает владение доменом.
Ниже — «боевой» сценарий: делаем Cloudflare API Token с минимальными правами, настраиваем certbot-dns-cloudflare, выпускаем wildcard и включаем безопасное автопродление (renewal) с reload сервисов.
Когда DNS-01 лучше HTTP-01 и что важно знать заранее
DNS-01 выбирают, когда нужно:
получить wildcard (Let’s Encrypt не выдаёт wildcard через HTTP-01);
выпустить сертификат для сервиса без публичного веб-доступа по 80/443;
валидировать домены, которые проксируются через Cloudflare (оранжевое облако), не меняя трафик на origin.
При этом заранее учитывайте нюансы:
DNS-пропагация: TXT-записи должны успеть «разойтись». В Cloudflare это обычно быстро, но иногда требуется подождать.
Безопасность токена: API Token — секрет, дающий право менять DNS. Храните его с правами
600и не светите в логах/репозиториях.Границы зоны: если у вас несколько зон или частичная делегация, токен должен быть ограничен именно той зоной, где создаётся
_acme-challenge.
Подготовка: что нужно в Cloudflare и на сервере
На стороне Cloudflare
Нужен API Token, который может редактировать DNS-записи в конкретной зоне. Global API Key лучше не использовать: токен проще ограничить и затем отозвать без побочных эффектов.
Проверьте до старта:
домен добавлен в Cloudflare и зона активна;
вы управляете нужной зоной (например,
example.com), а не только одной записью;вы понимаете, где будет жить сертификат: на origin (Nginx/Apache), в балансировщике, в контейнерах и т.д.
На стороне сервера
Нужны Certbot и плагин Cloudflare. На Debian/Ubuntu часто удобнее ставить через snap, чтобы получить свежие версии и меньше конфликтовать с пакетами из репозиториев.
sudo apt-get update
sudo apt-get install -y snapd
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
Проверьте версию:
certbot --version
Установите плагин DNS для Cloudflare:
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
Если вы планируете держать проекты на сервере провайдера, где уже есть удобная базовая инфраструктура (firewall, бэкапы, быстрый доступ к консоли), чаще всего проще делать это на VDS: DNS-01 не требует открывать 80/443 для валидации и хорошо подходит для приватных сервисов.

Создаём Cloudflare API Token с минимальными правами
Токен для DNS-01 должен уметь:
читать параметры зоны (чтобы плагин мог найти нужную zone_id);
создавать и удалять TXT-записи для
_acme-challenge.
Обычно достаточно таких прав:
Zone: Read
DNS: Edit
И обязательно ограничьте токен конкретной зоной: Zone Resources → Include → Specific zone → нужный домен. Это резко снижает ущерб при утечке.
Практика: токен для Certbot не должен уметь менять firewall rules, workers, page rules и всё остальное. Только DNS-редактирование и чтение зоны.
Сохраните значение токена в безопасном месте: Cloudflare покажет его один раз.
Настраиваем файл credentials для certbot-dns-cloudflare
Плагину нужен файл с токеном. Разместим его в /etc/letsencrypt и зададим строгие права.
sudo mkdir -p /etc/letsencrypt
sudo nano /etc/letsencrypt/cloudflare.ini
Содержимое:
dns_cloudflare_api_token = CF_API_TOKEN_VALUE
Права и владелец:
sudo chown root:root /etc/letsencrypt/cloudflare.ini
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
Дальше важно не «размножать» этот файл по проектам и не копировать его в контейнеры без необходимости. Лучше один защищённый секрет на хосте и один процесс обновления.
Выпуск wildcard и основного домена одним сертификатом
Частый кейс: сертификат нужен и на корень домена, и на все поддомены. В запросе указывают два имени: example.com и *.example.com.
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d example.com -d '*.example.com'
Флаги для автоконфигурации веб-сервера (nginx/apache) здесь не нужны: мы получаем «чистые» файлы в /etc/letsencrypt/live/example.com/ и дальше подключаем их куда требуется.
Итоговые файлы:
fullchain.pem— сертификат + цепочка;privkey.pem— приватный ключ;chain.pem— цепочка;cert.pem— сертификат без цепочки.
Если валидация не проходит из-за DNS
Если видите ошибки уровня «TXT record not found» или «NXDOMAIN», проверьте:
права токена: Zone:Read и DNS:Edit, и ограничение нужной зоной;
что домен в команде соответствует зоне (например,
sub.example.comвалидируется в зонеexample.com, если DNS управляется там);что параллельно не бежит второй ACME-клиент, который тоже пытается писать в
_acme-challenge.
Часто помогает увеличить ожидание пропагации:
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini --dns-cloudflare-propagation-seconds 120 -d example.com -d '*.example.com'
Подключаем сертификат к Nginx/Apache и не забываем про reload
В эксплуатации критичны два момента:
процесс веб-сервера должен иметь доступ к
fullchain.pemиprivkey.pem(обычно Nginx/Apache читают ключи на старте/перезагрузке под root);после продления нужен reload, иначе процесс продолжит использовать старый сертификат из памяти.
Типовые строки (как текст):
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Если нужна расширенная практика по выпуску/обновлению сертификатов и аккуратной настройке безопасности на уровне веб-сервера, полезно держать под рукой материал про HTTPS, Certbot и HSTS в типовом продакшене.
Настраиваем автоматический renewal и безопасный перезапуск сервисов
Сертификаты Let’s Encrypt короткоживущие, поэтому renewal — обязательная часть настройки. В snap-сборке Certbot обычно ставит systemd timer, который выполняет certbot renew дважды в сутки.
Проверка таймеров:
systemctl list-timers | grep -i certbot
Проверка статуса (имя юнита может отличаться, но в snap часто такое):
systemctl status snap.certbot.renewal.service
Чтобы сервисы подхватывали новый сертификат, используйте deploy-hook: он выполняется только если сертификат реально обновился.
Nginx:
sudo certbot renew --deploy-hook 'systemctl reload nginx'
Apache:
sudo certbot renew --deploy-hook 'systemctl reload apache2'
Если надо перезагружать несколько компонентов (например, nginx и haproxy), удобнее сделать короткий root-скрипт и вызывать его из deploy-hook, чтобы централизовать логику и логирование.
Тестируем renewal «как будет в проде»
Проверка, которую стоит сделать сразу после выпуска:
sudo certbot renew --dry-run
Если dry-run проходит без ошибок Cloudflare API, значит связка работает и без ручного вмешательства.
Диагностика: типовые ошибки и куда смотреть
1) Неверные права токена или токен от другой зоны
Симптомы: 403, authentication error, insufficient permissions в выводе Certbot.
Решение: выпустить новый токен с Zone:Read и DNS:Edit, ограничить нужной зоной. Убедиться, что в cloudflare.ini лежит актуальный токен, а не «похожая строка из заметок».
2) Валидация не видит TXT-запись
Симптомы: Let’s Encrypt пишет, что TXT не найден.
Самые частые шаги:
увеличить
--dns-cloudflare-propagation-secondsдо 60–180;проверить, что DNS реально обслуживается Cloudflare (NS на домене указывают на Cloudflare, нет частичной делегации в другое место);
проверить отсутствие конфликтов TXT на
_acme-challengeпри параллельных выпусках.
3) Сертификат обновился, но клиенты видят старый
Симптомы: certbot renew отработал, файлы обновились, но снаружи дата прежняя.
Почти всегда это отсутствие reload у сервиса. Добавьте deploy-hook и убедитесь, что команда reload действительно выполняется и не падает (смотрите журналы systemd и логи веб-сервера).
4) Упираетесь в rate limits
Если вы автоматизируете выпуск в CI или часто пересоздаёте окружения, тестируйте на staging и не выпускайте новый «боевой» сертификат на каждый прогон. Для стабильной инфраструктуры достаточно настроенного renewal.
Рекомендации по эксплуатации: чтобы wildcard жил спокойно
Один сертификат — один «владелец». Не запускайте два разных ACME-клиента, которые одновременно продлевают один набор имён.
Секреты отдельно.
/etc/letsencrypt/cloudflare.ini— только root, права600, без копий в репозитории и CI-логи.Логи и контроль сроков. Иногда достаточно раз в месяц смотреть
/var/log/letsencrypt/letsencrypt.logи держать напоминание на срок действия.Reload предпочтительнее restart. Для Nginx/Apache безопаснее
reload, чтобы не ронять соединения.
Если хотите более «универсальную» схему DNS-01, независимую от конкретного DNS-провайдера, посмотрите заметку про DNS-01 через acme-dns — полезно, когда домены размазаны по разным зонам и аккаунтам.
Короткий чеклист (можно в закладки)
Создать Cloudflare API Token: Zone:Read + DNS:Edit, ограничить конкретной зоной.
Положить токен в
/etc/letsencrypt/cloudflare.ini, права600.Установить Certbot и
certbot-dns-cloudflare(лучше одним способом установки, без «зоопарка»).Выпустить сертификат:
-d example.com -d '*.example.com'.Проверить
sudo certbot renew --dry-run.Настроить deploy-hook на reload сервиса после успешного renewal.
Итог: связка DNS-01 + Cloudflare API Token может работать годами без ручного вмешательства — TXT-записи создаются и удаляются автоматически, wildcard регулярно продлевается, а вам остаётся контролировать секреты и изменения в DNS-зонах (переезды, делегации, смены аккаунтов).



