Как перестать зависеть от Cloudflare в DNS и не выстрелить себе в ногу

от автора

DNS — это та штука, которую замечаешь только когда она падает. Весь твой трафик, почта, сертификаты, доступ к админкам — всё висит на том, что кто-то корректно ответит на запрос «а где example.com?». У меня этим «кем-то» был Cloudflare. Для большинства это правильный выбор — удобно, быстро, бесплатно. Но в какой-то момент я поймал себя на мысли, что фундамент всей моей инфраструктуры я не контролирую: он живёт в чужом дашборде, по чужим правилам и лимитам.

Я перенёс все свои зоны — несколько десятков доменов — на собственную DNS-инфра- структуру. Ниже — зачем, какая получилась архитектура, и обо что я споткнулся по дороге.

TL;DR

PowerDNS как скрытый мастер, пул авторитативных NSD-edge’ов в разных странах, автоматический экспорт зон каждые 5 минут, wildcard-сертификаты через ACME DNS-01 и разделение доменов по юрисдикциям. Всё описано как код, добавление зоны — пара API-вызовов. Грабли — в конце, они интереснее архитектуры.

Зачем вообще уходить с Cloudflare

Чтобы сразу снять вопрос: я не агитирую уходить. Если у вас пара доменов и нет особых требований — оставайтесь на managed-DNS, это разумно и дёшево. Мои причины были конкретными:

  1. Контроль. DNS — точка, через которую проходит вообще весь трафик. Я хотел владеть ею целиком: своя логика, свои TTL, свои записи без оглядки на лимиты и капризы дашборда.

  2. Разделение по юрисдикциям. Часть доменов российские, часть международные. Я хотел разные пулы авторитативных серверов в соответствующих регионах, а не один общий провайдер на всех.

  3. Отказоустойчивость на своих условиях. Несколько независимых edge-нод, которые я контролирую, вместо «доверьтесь, у нас всё хорошо».

  4. Образовательный интерес. Поднять production-grade authoritative DNS — лучший способ перестать бояться этой темы. Спойлер: сработало.

Архитектура

Классическая схема hidden master + authoritative slaves, но с парой нюансов.

                  ┌─────────────────────┐                  │  PowerDNS (master)  │  ← скрытый, не виден извне                  │  API + БД зон       │                  └─────────┬───────────┘                            │  экспорт зон (BIND-формат) каждые 5 мин                            ▼                  ┌─────────────────────┐                  │  узел раздачи       │  ← rsync архива зон + sha256                  └─────────┬───────────┘              ┌─────────────┼──────────────┐              ▼             ▼              ▼        ┌──────────┐  ┌──────────┐   ┌──────────┐        │ NSD edge │  │ NSD edge │ … │ NSD edge │  ← авторитативные, публичные        │  (RU)    │  │ (не-RU)  │   │ (не-RU)  │        └──────────┘  └──────────┘   └──────────┘
  • PowerDNS держит зоны в БД и отдаёт API. Он скрытый мастер: наружу его NS не светятся, поверхность атаки минимальна.

  • Экспортёр раз в 5 минут вытягивает зоны через API в BIND-формат, пакует, считает контрольную сумму (sha256) и кладёт архив на узел раздачи. Контрольная сумма — чтобы edge не подхватил полузаписанный или битый архив.

  • NSD-edge’ы — лёгкие, быстрые, авторитативные серверы, по которым и резолвятся домены. Они забирают свежий архив зон, сверяют сумму и перезагружаются.

  • Пулы NS по юрисдикциям. Российские домены делегированы на пул RU-нод, международные — на пул зарубежных. Делегирование на уровне регистратора указывает на нужный пул.

Почему NSD на краю, а не PowerDNS везде? NSD — узкоспециализированный авторитативный сервер: меньше поверхность атаки, предсказуемее под нагрузкой, проще держать «тонким». Вся умная логика и управление — в одном месте, на мастере. Edge тупой и быстрый — таким он и должен быть.

Сертификаты: wildcard через ACME DNS-01

Раз DNS свой — грех не использовать DNS-01 для wildcard-сертификатов. acme.sh ходит в API PowerDNS, ставит _acme-challenge TXT-запись, и я получаю *.example.com без возни с HTTP-валидацией на каждой ноде. Сертификаты централизованно раскатываются на нужные серверы. Один механизм на все домены вместо зоопарка валидаций.

Грабли

1. acme.sh и sudo. acme.sh демонстративно отказывается работать из-под sudo: «It seems that you are using sudo, please don’t use sudo to run this command». Лечится запуском с явной очисткой sudo-переменных окружения и HOME=/root. Мелочь, но выедает полчаса, если не знаешь, что он специально так себя ведёт.

2. Зарубежная нода, до которой «не доходят пакеты». Прямой SSH/rsync до одного из заокеанских серверов периодически рвался — часть пакетов терялась где-то на маршруте. Лечение в две руки: ходить туда через промежуточный узел как ProxyJump, а в хук синхронизации зон добавить таймаут на каждую edge-ноду, чтобы одна «залипшая» не вешала весь прогон экспорта. Второе — важнее: пока таймаута не было, одна больная нода тормозила обновление зон на всех здоровых.

3. Битый apt через кэширующий прокси. На одной из машин apt update упорно отдавал BADSIG на InRelease. Полчаса я подозревал репозиторий — а виноват оказался кэширующий прокси (apt-cacher-ng), который закэшировал битый файл и честно отдавал его снова и снова. Чистка кэша конкретного репозитория — и всё поехало. Мораль: между тобой и проблемой может стоять слой, о котором ты забыл.

4. Дубликат apt-источника с разными ключами. На другой ноде не ставился angie: два deb-источника на один репозиторий, но с разными signed-by-ключами → Conflicting values set for option Signed-By. Убрать лишнюю строку — и готово. Классика накопившейся вручную конфигурации.

5. Конфликт reuseport при HTTP/3. Когда позже включал HTTP/3, выяснилось: listen 443 quic reuseport; нельзя ставить в нескольких server-блоках, раскиданных по разным конфиг-файлам — получишь duplicate listen option. Либо reuseport ровно в одном месте, либо (проще для мультифайловой раскладки) опустить его вовсе.

6. Над-широкие правки SOA. При массовой правке зон легко зацепить те, что уже не на твоих NS — старые делегированные копии, которые ты держишь «на всякий». Стоит заранее разделить зоны на «мои NS» и «ещё на стороне» и не трогать вторые скопом. Иначе правишь то, что наружу всё равно не отдаётся, и путаешься в том, что реально живо.

Что это дало

  • Все зоны управляются из одного места — через API и как код. Добавить домен — пара вызовов, а не клики в дашборде.

  • Делегирование разнесено по юрисдикциям, edge-ноды независимы: падение одной не роняет резолвинг.

  • Wildcard-сертификаты выписываются автоматически через свой же DNS.

  • Ноль зависимости от чужого дашборда, его лимитов и его решений.

  • Прогон экспорта идемпотентный, добавление зоны предсказуемо.

Честный минус: это инфраструктура, которую теперь надо эксплуатировать самому. Managed DNS вы не патчите и не мониторите — а свой придётся. Для меня это осознанный размен контроля на ответственность.

Кому это нужно, а кому нет

Не нужно, если у вас пара доменов без особых требований — managed-DNS закрывает 99% случаев, и это нормально.

Оправдано, когда есть много зон, требования по контролю или юрисдикции, либо когда DNS — часть вашего продукта и зависеть в нём от третьей стороны не хочется.

PS А ещё могут случиться блокировки…

ссылка на оригинал статьи https://habr.com/ru/articles/1041894/