OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

ACME DNS‑01 через RFC2136: свой DNS‑API без облаков

DNS‑01 решает выпуск wildcard и закрытых сервисов, но нужен API к авторитетному DNS. Покажу, как поднять свой «API» на RFC2136: BIND + TSIG + nsupdate, интеграция с Certbot и acme.sh, безопасность, TTL, отладка и автоматизация продления без простоя.
ACME DNS‑01 через RFC2136: свой DNS‑API без облаков

Если вы держите авторитетный DNS сами (BIND, Knot, PowerDNS с поддержкой динамических обновлений) и хотите полностью автономную выдачу сертификатов, связка ACME DNS‑01 + RFC2136 даёт именно это: никакой внешней DNS‑панели, свои ключи и политика доступа, полная автоматизация wildcard. Ниже — практическая инструкция: от TSIG‑ключа и update-policy в BIND до работы с Certbot и acme.sh, плюс контроль за TTL, репликацией и безопасностью.

Что решает ACME DNS‑01 и почему именно RFC2136

Проверка DNS‑01 требует, чтобы вы добавили TXT‑запись вида _acme-challenge.example.com с конкретным значением. В отличие от HTTP‑01, тут не нужен публичный веб‑порт и не важно, стоит ли перед сайтом CDN/WAF, а wildcard поддерживается из коробки. Главный вопрос: как автоматом создавать и удалять TXT без ручного клика в панели? Ответ — динамические DNS‑обновления по RFC2136, подписанные TSIG. Если нужно глубже про сценарии wildcard и пайплайны — посмотрите наш материал Автоматизация wildcard через DNS‑01: практики и пайплайны.

RFC2136 реализован в BIND и многих других авторитетных серверах. Клиент (ACME‑бот) делает nsupdate с TSIG‑подписью, сервер валидирует и вносит изменения в зону. Вторички получают их по IXFR/NOTIFY так же, как любые другие изменения.

Архитектура: кто с кем общается

Схема простая:

  • ACME‑клиент (Certbot, acme.sh, lego) генерирует токен и создаёт TXT‑запись через RFC2136 на вашем авторитетном DNS;
  • ваш первичный DNS применяет изменение, уведомляет вторички;
  • валидация ACME‑центра проходит, когда произвольный рекурсор прочитает TXT из вашей зоны;
  • после выпуска TXT удаляется тем же способом.

Критично, чтобы: 1) ключ TSIG имел минимальные права, 2) изменение попадало на вторички достаточно быстро, 3) TTL TXT был невысоким, 4) порт 53 был доступен с хоста, где работает ACME‑клиент.

Фрагмент конфигурации BIND с update-policy для _acme-challenge и TSIG-ключ

Подготовка: что нужно заранее

  • Доступ к первичному авторитетному серверу (например, BIND 9.11+), где вы можете править named.conf и файлы зон.
  • Связь ACME‑клиента с BIND по TCP/UDP 53 (по возможности — внутренняя сеть/VPN).
  • Синхронизация времени (NTP/Chrony) — TSIG чувствителен к рассинхрону времени.
  • Адекватные TTL/серийники зон, корректная репликация на вторички.

Если вы хотите держать BIND изолированно, поднимайте его на отдельном сервере — подойдёт управляемый облачный VDS для авторитетного DNS.

TSIG‑ключ: создаём и храним правильно

Сгенерировать TSIG для BIND можно так:

tsig-keygen -a hmac-sha256 acme-key > /etc/bind/keys/acme-key.key
chown root:named /etc/bind/keys/acme-key.key
chmod 640 /etc/bind/keys/acme-key.key

Внутри файла вы получите блок key с algorithm и secret. Не публикуйте его. Для разделения прав лучше создавать отдельный ключ на зону или даже на подзону для _acme-challenge.

BIND: минимально необходимые настройки

Вариант A: точечный доступ через update-policy

Подключите ключ в общий конфиг и выдайте права только на TXT для _acme-challenge. Пример:

key "acme-key" {
  algorithm hmac-sha256;
  secret "XXXXXXXXXXXXXXXXXXXXXXXXXXXX==";
};

zone "example.com" IN {
  type master;
  file "/var/lib/bind/db.example.com";
  update-policy {
    grant acme-key name _acme-challenge.example.com. TXT;
  };
  allow-transfer { x.x.x.x; y.y.y.y; };
  also-notify { x.x.x.x; y.y.y.y; };
};

Такой update-policy разрешит только изменения TXT по нужному имени. Это намного безопаснее, чем глобальный allow-update.

Вариант B: выделенная подзона для ACME

Для чистоты и многосайтовых конфигураций удобно вынести _acme-challenge.example.com в отдельную зону и делегировать её на тот же ваш первичный DNS. Тогда политика доступа применяется к всей подзоне, а основная зона остаётся неизменяемой через RFC2136.

zone "_acme-challenge.example.com" IN {
  type master;
  file "/var/lib/bind/db._acme-challenge.example.com";
  update-policy {
    grant acme-key subdomain _acme-challenge.example.com. TXT;
  };
};

В основной зоне example.com добавьте NS‑делегирование для _acme-challenge на ваш авторитетный сервер.

Проверяем RFC2136 вручную: nsupdate

Перед интеграцией с ACME убедитесь, что динамическое обновление проходит:

nsupdate -k /etc/bind/keys/acme-key.key -v
server 10.0.0.10 53
zone example.com
update add _acme-challenge.example.com. 60 IN TXT "test-token-123"
send

Проверьте запись с рекурсивного резолвера (убедитесь, что вторички успели получить IXFR):

dig +short TXT _acme-challenge.example.com

Удалите тестовую запись:

nsupdate -k /etc/bind/keys/acme-key.key -v
server 10.0.0.10 53
zone example.com
update delete _acme-challenge.example.com. TXT
send

Если всё ок — интеграция с ACME‑клиентом пройдёт без сюрпризов.

Certbot: плагин dns‑rfc2136

У Certbot есть официальный плагин для RFC2136. Установите его пакетным менеджером вашей ОС. Далее создайте файл с секретами:

cat > /etc/letsencrypt/rfc2136.ini << 'EOF'
# доступ к первичному DNS
certbot_dns_rfc2136:dns_rfc2136_server = 10.0.0.10
certbot_dns_rfc2136:dns_rfc2136_port = 53

# имя TSIG-ключа и алгоритм
certbot_dns_rfc2136:dns_rfc2136_name = acme-key
certbot_dns_rfc2136:dns_rfc2136_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXX==
certbot_dns_rfc2136:dns_rfc2136_algorithm = HMAC-SHA256
EOF
chmod 600 /etc/letsencrypt/rfc2136.ini

Выпускаем сертификат с DNS‑01:

certbot certonly --agree-tos --email admin@example.com --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini --dns-rfc2136-propagation-seconds 60 -d example.com -d *.example.com

--dns-rfc2136-propagation-seconds выставляйте с запасом, учитывая репликацию на вторички и кэш рекурсоров. После успешного выпуска настройте автоматические перезагрузки служб по хукам Certbot или системному таймеру.

acme.sh: dns_rfc2136

acme.sh тоже умеет RFC2136. Минимальный набор переменных окружения:

export RFC2136_SERVER="10.0.0.10"
export RFC2136_PORT="53"
export RFC2136_KEY="acme-key"
export RFC2136_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXX=="
export RFC2136_ALGO="HMAC-SHA256"
export RFC2136_ZONE="example.com"

acme.sh --issue --dns dns_rfc2136 -d example.com -d *.example.com

acme.sh по умолчанию поставит cron‑задание для автопродления. Добавьте команду деплоя в веб‑сервер, чтобы бесшовно подхватывать новый сертификат.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

TTL, кэширование и скорость валидации

Ключевой параметр — низкий TTL для _acme-challenge. Ставьте 60–120 секунд. Помните о негативном кэшировании: если рекурсор успел получить NXDOMAIN/NOERROR NODATA, он может кэшировать «отсутствие» записи до значения из SOA (Negative TTL). Держите SOA негативный TTL разумным (например, 60–120).

После update первичный отправляет NOTIFY, вторички берут IXFR. Если вторички медленные или фильтруют IXFR, увеличьте задержку --dns-rfc2136-propagation-seconds или поправьте сетевые правила между DNS‑серверами.

Безопасность: минимальные привилегии и изоляция

  • Используйте update-policy вместо allow-update. Гранулируйте права: только TXT для _acme-challenge, без A/AAAA/CNAME.
  • Храните TSIG‑ключи с правами 600/640, отделяйте ключи по зонам и сервисам, регулярно ротируйте.
  • Ограничьте доступ к RFC2136 по сети (firewall), предпочитайте внутреннюю подсеть/VPN. Откройте 53/TCP и 53/UDP только с хоста, где крутится ACME‑клиент.
  • В BIND используйте view, если у вас split‑horizon: права обновления задавайте в «внутреннем» представлении, а не в публичном. Детальнее — в статье Split‑horizon (views) в BIND: настройка и подводные камни.
  • Логи: включите category update, чтобы быстро искать, кто, когда и что обновил.
  • Выбирайте алгоритм TSIG не ниже hmac-sha256.

DNSSEC и DNS‑01

DNSSEC и RFC2136 прекрасно совместимы: BIND подпишет динамические изменения, если зона в инлайн‑режиме подписания. Убедитесь, что ключи KSK/ZSK доступны и inline-signing yes; активирован для зоны. Проверьте, что вторички также поддерживают DNSSEC‑данные или получают их по IXFR.

Команды Certbot dns-rfc2136 и acme.sh, схема валидации и распространения DNS

Многозоновые и мультипроектные инсталляции

Для десятков доменов используйте делегирование подзоны _acme-challenge на единый ACME‑DNS кластер. Это упрощает разграничение прав: одно и то же приложение сможет обновлять TXT только в своих подзонах, не трогая основную зону.

Если BIND — только часть инфраструктуры (например, вторички у внешнего провайдера), убедитесь, что у них включён NOTIFY/IXFR и нет избыточных задержек на синхронизацию. Для больших зон контролируйте серийник и используйте ixfr-from-differences yes; для минимизации диффов.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Интеграция с веб‑серверами

После выпуска/обновления сертификатов нужно сообщить об этом фронтенду. Типовые команды перезагрузки без простоя:

  • Nginx: nginx -s reload
  • Apache: apachectl graceful

В Certbot используйте флаги --deploy-hook, в acme.sh--reloadcmd или готовые deploy‑скрипты. Следите за правами на ключи и цепочки: веб‑сервер должен читать файлы, но не иметь права на запись.

Диагностика и отладка

  • TXT не виден: проверьте dig @primary и dig @secondary, сравните SOA‑серийник. Убедитесь, что nsupdate делал корректную zone и полное имя с точкой.
  • ACME валидирует слишком рано: увеличьте задержку распространения, снизьте негативный TTL SOA.
  • REFUSED при nsupdate: нет права по update-policy, не совпадает имя ключа или алгоритм.
  • TSIG BADTIME: рассинхрон часов. Проверьте NTP/Chrony.
  • NXDOMAIN/NOERROR NODATA у внешних рекурсеров: ждите окончание кэша, проверьте делегирование подзоны и NS‑записи.

Практические советы по надёжности

  • Держите TTL TXT 60–120 при выпуске и поднимайте до 300+ в спокойное время (не обязательно, но полезно при кэшах).
  • Разделите роли: один ключ на один сервис/CI. Так проще отзывать доступ.
  • Логируйте и алертите: просадка update или медленные IXFR — повод оповестить on‑call.
  • Проверяйте лимиты эмитента сертификатов и распределяйте выпуски/продления во времени. Полезно помнить про ограничения — см. заметку о лимитах SAN и автоматизации: Лимиты Let’s Encrypt и стратегии автоматизации.

Чек‑лист внедрения

  1. Сгенерировать TSIG и положить в защищённый путь.
  2. Добавить key и update-policy в named.conf для зоны или подзоны.
  3. Сделать делегирование _acme-challenge при необходимости.
  4. Проверить nsupdate add/delete с низким TTL.
  5. Убедиться в корректной репликации на вторички.
  6. Подключить Certbot или acme.sh, задать задержку распространения.
  7. Настроить безпростой reload веб‑сервера по хуку.
  8. Прописать мониторинг логов и серийника зоны.
  9. Ограничить сетевой доступ к 53/TCP,UDP только от ACME‑клиента.
  10. Задокументировать ротацию TSIG и план восстановления.

FAQ

Можно ли выпускать wildcard только для поддомена? Да. При update-policy укажите конкретное имя, например _acme-challenge.app.example.com., и выпускать *.app.example.com.

Нужен ли TCP 53 для RFC2136? Да, лучше включать и UDP, и TCP. Некоторые реализации переходят на TCP для надёжной доставки обновления.

Как быстро менять ключ TSIG? Создайте новый ключ, добавьте его в named.conf, расширьте update-policy на оба ключа, переведите клиентов, затем удалите старый.

Что с split‑horizon (views)? Делайте обновления во «внутренней» view, но убедитесь, что зона одна и та же, и внешняя view обслуживает те же данные после подписи/репликации.

Итоги

ACME DNS‑01 через RFC2136 — это «собственный DNS‑API» без привязки к провайдерским интеграциям. Он отлично подходит для приватных сервисов, wildcard и сложных сетевых режимов. Правильно настроенный BIND с update-policy, аккуратный TSIG и дисциплина с TTL/репликацией превращают выпуск и продление в рутину. Если нужен коммерческий сертификат — посмотрите наши SSL-сертификаты.

Поделиться статьей

Вам будет интересно

systemd-run: ограничиваем CPU и RAM для одноразовых задач и интерактивных команд OpenAI Статья написана AI (GPT 5)

systemd-run: ограничиваем CPU и RAM для одноразовых задач и интерактивных команд

Как быстро ограничить CPU и память для разовых команд без unit-файлов: используем systemd-run, transient units в режимах --service ...
OpenSearch на VDS: практический гид по памяти JVM heap, ISM-политикам и снапшотам OpenAI Статья написана AI (GPT 5)

OpenSearch на VDS: практический гид по памяти JVM heap, ISM-политикам и снапшотам

Поднимем OpenSearch на VDS: настроим JVM heap без сюрпризов с GC, спроектируем ISM с rollover и удалением, организуем регулярные s ...
Gitea на VDS: установка, systemd, SSL и Nginx reverse proxy OpenAI Статья написана AI (GPT 5)

Gitea на VDS: установка, systemd, SSL и Nginx reverse proxy

Самостоятельный Git без лишней тяжеловесности: развернём Gitea на VDS с обратным прокси Nginx и SSL. Оформим как systemd‑сервис, п ...