Выберите продукт

ACME DNS‑01 без API: поднимаем acme‑dns и автоматизируем выпуск

У DNS‑провайдера нет API, а нужен wildcard или бесшовная автоматизация Let’s Encrypt? Решение — acme‑dns. Разберём архитектуру, безопасную делегацию, установку и конфиг, интеграцию с certbot, нюансы TTL, IPv6, резервирование и траблшутинг. Пошагово — от нуля до автообновления.
ACME DNS‑01 без API: поднимаем acme‑dns и автоматизируем выпуск

DNS‑01 — надёжный способ валидации домена в ACME (Let’s Encrypt и др.), особенно когда нужен wildcard. Но часто упираемся в отсутствие DNS‑API у провайдера — автоматизация ломается. Выход — вынести только технические TXT‑ответы в отдельную авторитетную зону и управлять ими через свой небольшой сервис. Эту задачу как раз решает acme‑dns.

Когда нужен ACME DNS‑01 без API и чем помогает acme‑dns

Типичный кейс: у вас зона у регистратора или хостинг‑провайдера, где нет API для создания TXT. При HTTP‑01 может мешать фронтенд, CDN, редиректы или невозможность положить файлы. При wildcard без DNS‑01 вообще никуда.

acme‑dns — минималистичный авторитетный DNS‑сервер плюс HTTP‑API, который хранит и отдаёт ровно те TXT‑записи, которые требуется выставить для ACME‑проверок. Вы держите его на своём сервере, делегируете техническую подзону и один раз прописываете CNAME для _acme-challenge. Дальше — полностью автоматическая валидация и продление сертификатов без вмешательства.

Архитектура и поток запросов

Идея: постоянная CNAME‑прокладка от _acme-challenge вашего домена к уникальному хосту в зоне, которую обслуживает acme‑dns. Клиент (certbot/lego и др.) кладёт TXT через API в acme‑dns, а валидатор CA читает TXT по CNAME.

  • ACME‑клиент инициирует выпуск и получает challenge.
  • Клиент отправляет через API в acme‑dns значение TXT.
  • Ваша основная зона содержит CNAME: _acme-challenge.example.comxxxx.auth.example.com.
  • CA запрашивает TXT по CNAME, получает ответ от acme‑dns, валидация проходит.
  • Клиент забирает сертификат, а при продлении делает то же самое.

Делегирование подзоны auth.example.com на acme‑dns

Подготовка делегированной подзоны

Нужен отдельный поддомен, например auth.example.com, который вы делегируете на свой сервер с acme‑dns. Удобнее всего держать такой сервис на отдельной VM — например, на VDS, чтобы изолировать сетевые порты 53/80 и не мешать продакшен‑нагрузке.

  1. Выберите адрес сервера для acme‑dns, лучше выделенный публичный IPv4/IPv6.
  2. В основной зоне создайте записи:
    • ns1.auth.example.com. A 203.0.113.10AAAA, если есть IPv6).
    • auth.example.com. NS ns1.auth.example.com.
  3. TTL ставьте 300–600 на период настройки, потом можно поднять до 1800–3600.

Так вы делегируете обслуживание подзоны auth.example.com вашему серверу, где будет крутиться acme‑dns.

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

Установка acme‑dns

Дальше два пути: пакет дистрибутива или статический бинарь с systemd‑юнитом. Ниже — универсальный подход с отдельным пользователем и конфигом.

# Debian/Ubuntu: certbot и зависимости (пример)
apt update
apt install certbot python3-pip -y

# (Опционально) Плагин certbot для acme-dns
pip3 install --upgrade certbot-dns-acmedns

# Сервисный пользователь и каталоги
useradd --system --home-dir /var/lib/acme-dns --shell /usr/sbin/nologin acmedns
mkdir -p /etc/acme-dns /var/lib/acme-dns
chown -R acmedns:acmedns /var/lib/acme-dns

# Предполагается, что бинарь acme-dns уже в /usr/local/bin/acme-dns
# Проверьте права и наличие
which acme-dns || echo "Положите бинарь в /usr/local/bin/acme-dns"

Конфигурация acme‑dns

Пример конфигурации в стиле TOML для актуальных версий. Проверьте ключи под свою сборку (они могут называться чуть иначе в разных релизах), но логика секций одинакова.

# /etc/acme-dns/config.cfg
[general]
# Зона, которую обслуживает acme-dns
domain = "auth.example.com"
nsname = "ns1.auth.example.com"
nsadmin = "hostmaster.example.com"
# Статические записи в зоне (минимум NS и A/AAAA для ns1)
records = [
  "auth.example.com. NS ns1.auth.example.com.",
  "ns1.auth.example.com. A 203.0.113.10"
]

[dns]
# Авторитетный DNS-сервер: слушать 53/udp и 53/tcp
listen = "0.0.0.0:53"
protocol = "both"

[api]
# HTTP API для клиентов (certbot/lego и т.п.)
listen = "0.0.0.0:80"
# Ограничьте доступ к API. Минимум — ваша управляющая машина/подсеть
ip_whitelist = ["203.0.113.5", "198.51.100.0/24", "::1"]

[database]
engine = "sqlite3"
connection = "/var/lib/acme-dns/acme-dns.db"

[log]
level = "info"

Юнит systemd

# /etc/systemd/system/acme-dns.service
[Unit]
Description=acme-dns authoritative server
After=network-online.target
Wants=network-online.target

[Service]
User=acmedns
Group=acmedns
ExecStart=/usr/local/bin/acme-dns -c /etc/acme-dns/config.cfg
Restart=always
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now acme-dns
systemctl status acme-dns

Сетевые доступы

Откройте порты: 53/udp и 53/tcp для авторитетного DNS, 80/tcp для API.

# Пример с UFW
ufw allow 53
ufw allow 53/udp
ufw allow 80/tcp

# Проверка
ss -lntu | grep -E ":53|:80"

Первичная регистрация в acme‑dns и CNAME‑прокладка

Каждому домену нужно один раз получить уникальный поддомен в зоне auth.example.com и учётные данные для API. Это делается через регистрацию. Показан общий принцип; конкретная команда может отличаться в зависимости от используемого клиента.

# Регистрация (пример с curl).
# Замените на свой API-домен/порт из конфига acme-dns.
curl -s -X POST http://auth.example.com/register

В ответ вернётся JSON с полями вроде username, password, fulldomain, subdomain, allowfrom. Дальше в основной зоне вашего домена пропишите постоянный CNAME:

  • _acme-challenge.example.com. CNAME <fulldomain из ответа>.
  • Для wildcard достаточно такого же CNAME: _acme-challenge.example.com. CNAME <fulldomain>. Один и тот же CNAME подходит и для базового домена, и для *. SAN‑выпусков.

Важно: не ставьте TTL ниже 60–120 на CNAME в продакшене — слишком низкий TTL нагружает внешний DNS и может привести к непредсказуемым задержкам распространения кэшей валидатора.

Интеграция с certbot через плагин dns‑acmedns

Самый комфортный способ — официальные плагины, которые умеют ходить в API acme‑dns. Далее — пример с certbot.

  1. Установите плагин (см. выше pip3 install certbot-dns-acmedns).
  2. Подготовьте файл учётных данных для домена (600):
# /etc/letsencrypt/acmedns/example.com.json
{
  "api_url": "http://auth.example.com",
  "username": "USERNAME_FROM_REGISTER",
  "password": "PASSWORD_FROM_REGISTER",
  "fulldomain": "XXXX.auth.example.com",
  "subdomain": "XXXX",
  "allowfrom": []
}

chmod 600 /etc/letsencrypt/acmedns/example.com.json
  1. Выпустите сертификат с DNS‑01:
certbot certonly --dns-acmedns --dns-acmedns-credentials /etc/letsencrypt/acmedns/example.com.json --dns-acmedns-propagation-seconds 30 -d example.com -d *.example.com

При продлении certbot сам повторит DNS‑валидацию через acme‑dns — ручных действий больше не потребуется. Если у вас несколько доменов, подготовьте отдельные JSON‑файлы для каждого и используйте их в соответствующих командах/юнитах. Также посмотрите разбор по теме: Wildcard SSL по DNS‑01: разбор автоматизации и заметку о лимитах: Лимиты Let’s Encrypt для SAN и автоматизация.

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

Как это работает для SAN и нескольких доменов

Вы можете выпускать один сертификат с несколькими именами (-d несколько раз), включая wildcard. Для каждого домена нужен свой CNAME на fulldomain, который вы получили при регистрации в acme‑dns для этого домена. Один fulldomain можно переиспользовать для базового и wildcard имён одного домена.

Безопасность и контроль доступа

  • Ограничьте доступ к HTTP‑API по IP через ip_whitelist в конфиге acme‑dns и/или файрвол.
  • Храните файл учётных данных с правами 600; не коммитьте в VCS.
  • Включите IPv6 только если контролируете фильтрацию и маршрутизацию.
  • Если сервер многоарендный, изолируйте сервис: NoNewPrivileges, CapabilityBoundingSet, отдельный пользователь, резервная копия БД.

Надёжность: NS, TTL, бэкапы

  • Два NS лучше одного: поднимите второй acme‑dns инстанс на другой VM, добавьте второй NS и A/AAAA. Либо держите вторую копию в standby и переключайте NS при аварии.
  • IPv6: добавьте AAAA для ns1.auth.example.com, но проверьте фильтры 53/udp и 53/tcp.
  • TTL: 300–600 на период активной настройки, потом 1800–3600 для устойчивости кэшированию.
  • Бэкапы: снимайте /var/lib/acme-dns/acme-dns.db снапшотами. Для SQLite достаточно файловой копии при остановленном сервисе или с fs‑снимком.

Диагностика DNS‑валидации с dig +trace

Траблшутинг

Проверяем делегирование и ответы шаг за шагом:

# Видит ли мир делегирование подзоны
dig +short NS auth.example.com

# Отдаёт ли ваш сервер нужные записи
dig @203.0.113.10 auth.example.com SOA +noall +answer

dig @203.0.113.10 XXXX.auth.example.com TXT +noall +answer

# Полный путь валидации для домена
# Должно показать CNAME, затем TXT через CNAME
dig +trace _acme-challenge.example.com TXT
  • Сервис не слушает 53/udp: проверьте AmbientCapabilities=CAP_NET_BIND_SERVICE, файрвол, SELinux/AppArmor, привилегии пользователя.
  • TXT не видно: удостоверьтесь, что плагин отправил challenge в API, логи acme‑dns на info/debug.
  • CAA блокирует выпуск: проверьте CAA в основной зоне, разрешите выбранного CA.
  • DNSSEC: не включайте его на auth.example.com, если не уверены в корректности подписи и цепочек.
  • Задержки распространения: увеличьте --dns-acmedns-propagation-seconds до 60–120, особенно при сложных резолверах/Anycast.

Автоматизация продления

У certbot по умолчанию есть systemd‑таймер. Убедитесь, что он активен, и добавьте рестарт сервисов после обновления сертификата через deploy‑hook.

# Проверка таймера
systemctl list-timers | grep certbot || systemctl enable --now certbot.timer

# Пример продления с хуком перезагрузки nginx
certbot renew --deploy-hook "systemctl reload nginx"

Миграция на другой сервер

  1. Поднимите новый acme‑dns со схожим конфигом.
  2. Перенесите acme-dns.db и убедитесь, что ответы по XXXX.auth.example.com совпадают.
  3. Поменяйте A/AAAA у ns1.auth.example.com на новый IP. При двух NS — добавьте второй, снизьте TTL заранее.
  4. Проверьте валидацию и лишь затем выключайте старый сервер.

FAQ: часто задаваемые вопросы

Можно ли использовать один acme‑dns для многих доменов и клиентов?

Да. Регистрация даёт уникальный fulldomain и отдельные credentials на каждый домен. Храните их раздельно, доступ ограничьте по IP.

Нужен ли второй NS?

Рекомендуется. ACME‑валидация чувствительна к доступности авторитетного DNS. Два NS повышают шанс успешного запроса валидатора.

Что с wildcard и поддоменами?

Один fulldomain подходит и для example.com, и для *.example.com. Главное — один раз прописать CNAME для _acme-challenge.example.com.

Можно ли оставить API закрытым и выпускать только локально?

Да, если acme‑dns крутится на той же машине, где работает клиент. В этом случае оставьте ip_whitelist только с 127.0.0.1/::1, а клиент обращается к http://127.0.0.1.

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

  • Зарезервирован поддомен: auth.example.com.
  • Созданы A/AAAA для ns1.auth.example.com и делегирован NS для auth.example.com.
  • acme‑dns установлен, запущен, слушает 53/udp+tcp и 80/tcp.
  • API ограничено по IP, база бэкапится.
  • Получены credentials через регистрацию, в основной зоне прописан постоянный CNAME для _acme-challenge.
  • certbot настроен с плагином dns‑acmedns, сертификаты выпускаются и обновляются, хук перезагружает веб‑сервер. Для углубления почитайте ещё: HTTPS, certbot и HSTS.

С такой схемой вы отвязываетесь от возможностей DNS‑провайдера и получаете надёжную, воспроизводимую автоматизацию ACME DNS‑01 для одиночных доменов, wildcard и SAN‑сертификатов. Поддерживайте аккуратные TTL, мониторьте доступность 53/udp и регулярно проверяйте срок действия сертификатов — и внезапных ночных инцидентов станет заметно меньше. Если требуется не только бесплатный DV, но и коммерческие вариации — посмотрите наши SSL-сертификаты.

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

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

Rsync over SSH: ускоряем передачу и держим нагрузку под контролем (cipher, compression, bwlimit, IO) OpenAI Статья написана AI (GPT 5)

Rsync over SSH: ускоряем передачу и держим нагрузку под контролем (cipher, compression, bwlimit, IO)

Разберём, как разогнать rsync over SSH и не «положить» прод: как выбрать быстрый cipher (chacha20-poly1305 или aes128-gcm), когда ...
Reverse DNS (PTR): как работает rDNS, зачем нужен и как настроить без боли OpenAI Статья написана AI (GPT 5)

Reverse DNS (PTR): как работает rDNS, зачем нужен и как настроить без боли

Reverse DNS (PTR, rDNS) — запись, которая сопоставляет IP-адрес с hostname. Разберём, где живёт PTR, как проверить через dig -x, з ...
Postfix: deferred и bounce из‑за DNS и TLS — разбор очереди и быстрый план ремонта OpenAI Статья написана AI (GPT 5)

Postfix: deferred и bounce из‑за DNS и TLS — разбор очереди и быстрый план ремонта

Если письма в Postfix зависают со status=deferred или уходят в bounce, чаще всего причина в DNS (резолвинг, MX/A/AAAA, rDNS PTR, H ...