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

Split‑horizon DNS: views в BIND для DEV/STAGE/PROD

Split‑horizon DNS через views в BIND позволяет отдавать разные ответы из одной зоны для DEV/STAGE/PROD и внутренних сетей. В статье разбираем проектирование ACL, конфигурацию, зоны, TTL, безопасное тестирование с dig и rndc, трансферы, кэширование per‑view и подводные камни DNSSEC.
Split‑horizon DNS: views в BIND для DEV/STAGE/PROD

Классическая задача для админа: одинаковые имена, разные адреса для разных сред. Командам DEV нужны тестовые IP, STAGE — предбоевые, PROD — только боевые. Плюс приходится прятать внутренние сервисы от внешнего мира. Решение — split‑horizon DNS в BIND через механизм views, когда сервер выбирает зону и ответы в зависимости от того, кто спрашивает.

Зачем split‑horizon и как это работает в BIND

Split‑horizon DNS — это подход, при котором один и тот же домен (или имя) разрешается в разные IP в зависимости от клиента. В BIND это реализуется с помощью view: каждая view имеет свои ACL (match-clients), настройки рекурсии, свой кэш и собственные описания зон. По сути, вы поднимаете несколько «логических» DNS‑серверов внутри одного процесса.

Важно понимать, что порядок view в конфигурации имеет значение: BIND выбирает первую подходящую по match-clients. Ещё момент: у каждой view независимый кэш, что помогает избежать «протечек» записей между средами, но накладывает ответственность за отдельную диагностику и очистку кэша.

Если вы выбираете стек, посмотрите сравнение PowerDNS и BIND — это поможет принять решение на старте проекта.

Архитектурные варианты для DEV/STAGE/PROD

1) Один FQDN с разными ответами

Наиболее «чистый» split‑horizon: имя api.example.com в view DEV указывает на IP DEV, в STAGE — на STAGE, в PROD — на боевой. Плюсы: одинаковые конфиги приложений (имя не меняется). Минусы: выше риск человеческой ошибки и «прострела» — если перепутать файлы зон или ACL, можно отдать тестовый адрес в прод или наоборот.

2) Раздельные подзоны dev.example.com, stage.example.com

Консервативный подход: разные имена для разных сред. Он проще в обслуживании и понятнее новичкам, но требует дисциплины в приложениях (URL/конфиги отличаются между средами). Внутри views можно дополнительно скрывать внутренние подзоны от нецелевых сетей.

На практике часто комбинируют: единый FQDN с разными ответами для внутренних сетей и отдельные подзоны для внешних партнёров/аутсорсеров.

Поднимать авторитативный DNS удобнее на изолированном узле, например на VDS, где проще контролировать сеть, фаервол и обновления.

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

Проектирование ACL и критериев маршрутизации

Ключевой слой — ACL, по которым BIND определяет, в какую view отправить запрос. Обычно это:

  • Подсети разработчиков и CI (DEV).
  • STAGE‑сегменты, предбоевые кластеры, UAT‑VPN.
  • PROD‑сети (офис, дата‑центры, DMZ) и «все прочие».

Рекомендации:

  • Чётко документируйте диапазоны IP и держите один источник истины (например, отдельный include-файл acls.conf).
  • Ставьте наиболее «специфичные» ACL выше в списке views.
  • Не полагайтесь на match-destinations без необходимости — обычно достаточно match-clients.
  • Не используйте .local как TLD для внутренних зон (резерв mDNS). Лучше corp.example.com либо .internal без делегирования наружу.

Схема ACL и выбора view в BIND для DEV/STAGE/PROD

Базовая конфигурация BIND с views

Ниже — опорный пример. Адаптируйте имена зон, пути и сети под себя. Показан вариант, где один и тот же домен example.com имеет разные файлы зоны в DEV/STAGE/PROD. Добавлен «default» для всех прочих клиентов, чтобы отдавать только публично безопасный ответ.

# /etc/named.conf (или /etc/bind/named.conf)
acl devnets { 10.10.0.0/16; 172.16.10.0/24; };
acl stagenets { 10.20.0.0/16; 172.16.20.0/24; };
acl prodnets { 10.30.0.0/16; 192.168.100.0/24; };

options {
    directory "/var/named";
    listen-on { 0.0.0.0; };
    listen-on-v6 { any; };
    allow-query { any; };
    allow-recursion { none; };
    dnssec-enable yes;
    dnssec-validation auto;
};

logging {
    channel default_syslog { syslog daemon; severity info; };
    category default { default_syslog; };
    category queries { default_syslog; };
};

key "xfr-key" {
    algorithm hmac-sha256;
    secret "BASE64==";
};

server 192.0.2.2 { keys { xfr-key; }; };

view "dev" {
    match-clients { devnets; 127.0.0.1; ::1; };
    recursion yes;
    allow-recursion { devnets; localhost; };

    zone "example.com" IN {
        type master;
        file "zones/dev.example.com.zone";
        allow-transfer { key xfr-key; 192.0.2.2; };
        notify yes;
        also-notify { 192.0.2.2; };
    };
};

view "stage" {
    match-clients { stagenets; };
    recursion yes;
    allow-recursion { stagenets; };

    zone "example.com" IN {
        type master;
        file "zones/stage.example.com.zone";
        allow-transfer { key xfr-key; 192.0.2.2; };
        notify yes;
        also-notify { 192.0.2.2; };
    };
};

view "prod" {
    match-clients { prodnets; };
    recursion no;

    zone "example.com" IN {
        type master;
        file "zones/prod.example.com.zone";
        allow-transfer { key xfr-key; 192.0.2.2; };
        notify yes;
        also-notify { 192.0.2.2; };
    };
};

view "default" {
    match-clients { any; };
    recursion no;

    zone "example.com" IN {
        type master;
        file "zones/public.example.com.zone";
    };
};

Комментарий к важным опциям:

  • allow-recursion включаем только там, где реально нужно резолвить внешние записи (обычно для DEV/STAGE). В PROD для авторитативного ответчика — no.
  • allow-transfer и also-notify ограничиваем и защищаем TSIG‑ключом. Не отдавайте трансферы без аутентификации.
  • view "default" — страховка, чтобы «все остальные» не увидели внутренние адреса.

Шаблоны зон, TTL и различия между средами

Для DEV логично делать маленькие TTL (30–300 секунд) — удобно тестировать. Для PROD TTL выше (5–30 минут, иногда больше) — меньше нагрузка и колебания. Следите за SOA: увеличивайте serial при каждом изменении, выставляйте разумный negative TTL (поле SOA, второе справа) — например 60–300 секунд в DEV/STAGE и 300–900 в PROD.

;; zones/dev.example.com.zone
$TTL 60
@   IN SOA ns1.example.com. dns.example.com. (
        2025102301 ; serial
        1h         ; refresh
        10m        ; retry
        7d         ; expire
        60         ; negative TTL
)
    IN NS ns1.example.com.
    IN A  10.10.10.10
www IN A  10.10.10.20
api IN A  10.10.10.30

;; zones/stage.example.com.zone
$TTL 120
@   IN SOA ns1.example.com. dns.example.com. (
        2025102301 1h 10m 7d 120
)
    IN NS ns1.example.com.
    IN A  10.20.20.10
www IN A  10.20.20.20
api IN A  10.20.20.30

;; zones/prod.example.com.zone
$TTL 900
@   IN SOA ns1.example.com. dns.example.com. (
        2025102301 1h 10m 7d 300
)
    IN NS ns1.example.com.
    IN A  203.0.113.10
www IN A  203.0.113.20
api IN A  203.0.113.30

;; zones/public.example.com.zone (минимум, что безопасно отдать всем)
$TTL 900
@   IN SOA ns1.example.com. dns.example.com. (
        2025102301 1h 10m 7d 300
)
    IN NS ns1.example.com.
www IN A  203.0.113.20

Обратите внимание: если публичная зона делегирована у регистратора и подписана DNSSEC, то подход «одна и та же зона, разные ответы» требует особой аккуратности. Валидация может ломаться, если версии зоны внутри и снаружи подписаны по‑разному. Безопасная стратегия — держать публичную делегируемую зону с консистентной подписью, а внутренние ответы отдавать только внутренним сетям либо использовать отдельные подзоны. Если домен ещё не оформлен, начните с регистрации доменов, продумав делегирование и NS заранее.

Проверка конфигурации и публикация

Перед перезапуском прогоним валидацию:

named-checkconf -z
named-checkzone example.com /var/named/zones/dev.example.com.zone
named-checkzone example.com /var/named/zones/stage.example.com.zone
named-checkzone example.com /var/named/zones/prod.example.com.zone
named-checkzone example.com /var/named/zones/public.example.com.zone

Загружаем/перечитываем:

rndc reconfig
rndc reload

Тестируем из каждой подсети. Удобно использовать dig с привязкой исходного адреса (на хосте, где есть такие IP), либо запускать команды непосредственно из соответствующих сетевых зон.

dig @127.0.0.1 api.example.com +short
# С указанным исходным адресом (если интерфейс есть на сервере)
dig -b 10.10.0.10 @127.0.0.1 api.example.com +short  # ожидаем DEV IP
dig -b 10.20.0.10 @127.0.0.1 api.example.com +short  # ожидаем STAGE IP
dig -b 10.30.0.10 @127.0.0.1 api.example.com +short  # ожидаем PROD IP

Если видите неожиданные ответы, проверьте порядок view, ACL и наличие продублированных записей. Для очистки кэша по имени в конкретной view:

rndc flushname -view dev api.example.com
rndc flushname -view stage api.example.com
rndc flushname -view prod api.example.com

Примеры dig и очистки кэша view через rndc

AXFR/IXFR и резервные NS при views

Если у вас вторичные DNS, они тоже должны «понимать» нужные варианты зон. Есть два пути:

  • Поднять аналогичную конфигурацию views на вторичном, чтобы принимать соответствующие трансферы из каждой view.
  • Поддерживать разные имена зон/файлы и изолировать потоки трансферов по IP и TSIG‑ключам. Следите, чтобы вторичный отдавал клиентам те же ответы согласно своим views.

И не забывайте, что notify и allow-transfer настраиваются внутри каждой view, иначе второй сервер может получить не ту версию зоны.

Рекурсия, фильтры и внутренние зоны

Для внутренних клиентов обычно нужен рекурсивный резолв внешних доменов. Включайте recursion только там, где это действительно требуется, и ограничивайте allow-recursion. Внутренние зоны сервисов (например, internal.corp.example.com) добавляются как обычные zone внутри нужных views. Полезны «пустые зоны» RFC 1918/6303 для блокировки утечек PTR‑запросов наружу.

DNSSEC и split‑horizon

DNSSEC с views — тонкая тема. Отдавать разные данные под одной делегированной и подписанной зоной разным клиентам рискованно: валидаторы вне вашей сети могут получать RRSIG, не соответствующие данным. Безопасные стратегии:

  • Публичную зону держать консистентной и подписанной, а внутренние ответы — в непубличных подзонах без делегирования наружу.
  • Либо поддерживать отдельные делегирования и ключи для внутренних версий зон, изолированные от публичной цепочки доверия.

Если всё же требуется inline‑signing по views, тщательно протестируйте валидацию и кэширование со стороны внешних и внутренних резолверов. Для автоматизации DNS‑01 и wildcard‑сертификатов пригодится материал «Wildcard и DNS‑01: автоматизация».

FastFox VDS
Регистрация доменов от 99 руб.
Каждый проект заслуживает идеального доменного имени, выберите один из сотни, чтобы начать работу!

Типичные ошибки и как их избежать

  • Неверный порядок view: «широкая» any раньше «узкой» — все попадают не туда.
  • Забытый allow-query или allow-transfer на уровне зоны внутри нужной view.
  • Необновлённый SOA serial — вторички не получают изменения.
  • Слишком большие TTL в DEV/STAGE — медленная обратная связь при тестах.
  • Клиенты используют сторонние публичные резолверы, минуя ваш split‑horizon. Решение — политика на уровне DHCP/резолверов/файрвола.
  • NAT hairpin/loopback и асимметричная маршрутизация ломают match-clients. Тестируйте из реальных подсетей.
  • Смешение рекурсивного и авторитативного режимов без чётких границ allow-recursion.

Миграция с «одной зоны» на views без простоя

  1. Соберите список клиентов и сетей, которые должны видеть DEV/STAGE/PROD.
  2. Создайте ACL и черновики файлов зон для каждой среды.
  3. Добавьте view "default" с безопасной публичной зоной, но пока не переключайте клиентов.
  4. Включите views на одном из вторичных серверов и проверьте консистентность трансферов.
  5. Разверните views на основном, но временно включите повышенный лог запросов (category queries), проверьте тестами.
  6. Переключите клиентов по сегментам, проверяя dig/rndc и метрики.
  7. Зафиксируйте итоговую схему, отключите лишнюю детализацию логов.

Эксплуатационные советы

  • Автоматизируйте проверку: named-checkconf -z и named-checkzone в CI перед выкладкой зон в репозиторий.
  • Шаблонизируйте SOA и TTL. Единый стиль ускоряет ревью.
  • Используйте rndc reconfig для подхвата новых зон без полной перезагрузки, а rndc reload — для пересборки конкретной зоны.
  • Для ускорения массовых правок в DEV/STAGE держите TTL низкими и повышайте только перед релизом.
  • Помните про независимые кэши per‑view: чистка точечная через rndc flushname -view.

Итоги

Split‑horizon DNS на BIND через views — надёжная стратегия для разделения DEV/STAGE/PROD и внутренних зон. Ключ к успеху — корректные ACL, грамотный порядок view, дисциплина с TTL и SOA, защищённые трансферы и аккуратность с DNSSEC. Потратьте время на проектирование, автоматизируйте проверку и выкладку зон — и получите предсказуемые резолвы для всех сред без сюрпризов в продакшене.

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

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

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 ...
ACME DNS‑01 через RFC2136: свой DNS‑API без облаков OpenAI Статья написана AI (GPT 5)

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

DNS‑01 решает выпуск wildcard и закрытых сервисов, но нужен API к авторитетному DNS. Покажу, как поднять свой «API» на RFC2136: BI ...