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.com→xxxx.auth.example.com. - CA запрашивает TXT по CNAME, получает ответ от
acme‑dns, валидация проходит. - Клиент забирает сертификат, а при продлении делает то же самое.

Подготовка делегированной подзоны
Нужен отдельный поддомен, например auth.example.com, который вы делегируете на свой сервер с acme‑dns. Удобнее всего держать такой сервис на отдельной VM — например, на VDS, чтобы изолировать сетевые порты 53/80 и не мешать продакшен‑нагрузке.
- Выберите адрес сервера для
acme‑dns, лучше выделенный публичный IPv4/IPv6. - В основной зоне создайте записи:
ns1.auth.example.com. A 203.0.113.10(иAAAA, если есть IPv6).auth.example.com. NS ns1.auth.example.com.
- TTL ставьте 300–600 на период настройки, потом можно поднять до 1800–3600.
Так вы делегируете обслуживание подзоны auth.example.com вашему серверу, где будет крутиться acme‑dns.
Установка 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.
- Установите плагин (см. выше
pip3 install certbot-dns-acmedns). - Подготовьте файл учётных данных для домена (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
- Выпустите сертификат с 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 и автоматизация.
Как это работает для 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‑снимком.

Траблшутинг
Проверяем делегирование и ответы шаг за шагом:
# Видит ли мир делегирование подзоны
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"
Миграция на другой сервер
- Поднимите новый
acme‑dnsсо схожим конфигом. - Перенесите
acme-dns.dbи убедитесь, что ответы поXXXX.auth.example.comсовпадают. - Поменяйте A/AAAA у
ns1.auth.example.comна новый IP. При двух NS — добавьте второй, снизьте TTL заранее. - Проверьте валидацию и лишь затем выключайте старый сервер.
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-сертификаты.


