DNS по умолчанию слишком доверчив: открытый рекурсор отвечает кому угодно, отдаёт всю зону по AXFR любому желающему и принимает обновления без проверки. На LPIC-2 от вас ждут умения превратить такой named в закрытую крепость. В этом уроке мы изолируем процесс named, ограничим запросы и трансферы через ACL, защитим передачу зон ключами TSIG, подпишем зону DNSSEC и разведём ответы для внутренних и внешних клиентов через split-horizon. Работаем на BIND 9.18+ (актуален в Debian 13, Ubuntu 24.04, RHEL 10).

Как это работает
Изоляция нужна, чтобы взлом named не дал доступ ко всей системе. Исторически named запирали в chroot - подменяли корень файловой системы, чтобы процесс видел только свой каталог. В 2026 это легаси: пакетный named и так работает от непривилегированного пользователя (bind в Debian, named в RHEL), а реальную изоляцию даёт systemd через директивы юнита - ProtectSystem, PrivateTmp, CapabilityBoundingSet. Chroot оставляем только для экзамена и редких кастомных сборок.
Ограничение доступа строится на ACL - именованных списках адресов и сетей. Опция allow-query решает, кому вообще отвечать; allow-recursion - кому давать рекурсивные ответы (это главный рубеж против превращения в открытый резолвер и DDoS-усилитель); allow-transfer - кому отдавать копию зоны по AXFR. По умолчанию в BIND 9.18 рекурсия уже закрыта снаружи, но проверять надо явно.
TSIG (Transaction SIGnature) - симметричный ключ, общий для двух серверов. Им подписывается каждая транзакция: трансфер зоны (мастер - слейв) и динамические обновления (nsupdate). Получатель пересчитывает HMAC и сверяет подпись, плюс проверяет время - поэтому часы должны быть синхронизированы (chrony). TSIG защищает канал передачи, но не сами данные в кэше клиента.
DNSSEC - другая задача: он подписывает записи зоны парой ключей. ZSK (Zone Signing Key) подписывает данные, KSK (Key Signing Key) подписывает ZSK, а хэш KSK публикуется у родителя как запись DS. Резолвер строит цепочку доверия от корня вниз и отвергает подделку. Это защита целостности данных для всех, а не только канала между двумя серверами.
Split-horizon (split DNS) выдаёт разные ответы разным клиентам. В BIND это реализуют через views: каждый view имеет свой match-clients и свой набор зон. Внутренняя сеть видит реальные приватные адреса, внешний мир - только публичные записи. Порядок views важен - клиент попадает в первый подходящий.
Команды и примеры
ACL и ограничения в named.conf (Debian: /etc/bind/named.conf.options, RHEL: /etc/named.conf):
Код: Выделить всё
acl "trusted" { 10.0.0.0/8; 192.168.0.0/16; localhost; };
acl "slaves" { 203.0.113.5; 203.0.113.6; };
options {
allow-query { any; };
allow-recursion { trusted; }; // рекурсия только своим
allow-transfer { none; }; // глобально запретить, открыть в зоне
recursion yes;
};Код: Выделить всё
tsig-keygen -a hmac-sha256 xfer-key > /etc/bind/tsig.keyКод: Выделить всё
include "/etc/bind/tsig.key";
zone "example.com" {
type master;
file "/var/lib/bind/example.com.zone";
allow-transfer { key "xfer-key"; };
};Код: Выделить всё
server 198.51.100.10 { keys { xfer-key; }; };Код: Выделить всё
dnssec-keygen -a ECDSAP256SHA256 -f KSK example.com
dnssec-keygen -a ECDSAP256SHA256 example.comКод: Выделить всё
zone "example.com" {
type master;
file "/var/lib/bind/example.com.zone";
dnssec-policy default;
inline-signing yes;
};Код: Выделить всё
named-checkzone example.com /var/lib/bind/example.com.zone
delv @127.0.0.1 example.com SOA +rtrace
dig @127.0.0.1 example.com DNSKEY +dnssecSplit-horizon через views:
Код: Выделить всё
view "internal" {
match-clients { trusted; };
recursion yes;
zone "example.com" { type master; file "internal/example.com"; };
};
view "external" {
match-clients { any; };
recursion no;
zone "example.com" { type master; file "external/example.com"; };
};Код: Выделить всё
named-checkconf
rndc reconfig
systemctl reload named # RHEL: named, Debian: named (бывший bind9)- Открытый рекурсор: забыли allow-recursion - ваш сервер используют для DNS-amplification атак. Проверяйте dig +short test.openresolver.com TXT снаружи.
- allow-transfer { any; } - вся зона утекает любому через dig AXFR. Всегда привязывайте трансфер к key или slaves.
- Рассинхрон часов ломает TSIG: ошибка BADTIME. Держите chrony на мастере и слейвах.
- Идентичный ключ, но разные алгоритмы (hmac-md5 против sha256) в name ключа - подпись не сойдётся. Имя и алгоритм должны совпадать на обоих концах.
- После DNSSEC забыли отдать DS родителю - зона подписана, но цепочка доверия рвётся, валидаторы отдают SERVFAIL.
- При views ВСЕ зоны должны лежать внутри views, нельзя смешивать зоны на верхнем уровне и во view - named не стартует.
- Просрочка RRSIG: без dnssec-policy подписи надо переподписывать вручную, иначе через срок валидации зона "протухает".
- chroot в 2026: правка конфига в /etc/, а named читает копию в /var/named/chroot/etc/ - меняете не тот файл.
- Поднимите named на стенде, в options задайте acl "lan" со своей подсетью и allow-recursion { lan; }. Снаружи стенда проверьте, что рекурсия закрыта (dig вернёт REFUSED).
- Сгенерируйте TSIG-ключ через tsig-keygen, пропишите его и allow-transfer { key ...; } в зону. Попробуйте dig AXFR без ключа (откажет) и с ключом через -y (отдаст зону).
- Включите для зоны dnssec-policy default и inline-signing yes, перезагрузите named, дождитесь подписи.
- Снимите DNSKEY (dig DNSKEY +dnssec) и убедитесь, что появились RRSIG. Сгенерируйте DS через dnssec-dsfromkey.
- Запустите delv @127.0.0.1 для записи зоны и найдите строку о валидации.
- Разделите зону на internal и external views с match-clients и проверьте, что dig с localhost и с внешнего адреса отдают разные A-записи.
- Сломайте время на слейве (date -s) и поймайте ошибку TSIG BADTIME в логах.
- Чем allow-query отличается от allow-recursion и почему второе критично для безопасности?
- Что именно защищает TSIG, а что - DNSSEC, и почему это не одно и то же?
- Какую роль играют KSK, ZSK и DS-запись в цепочке доверия DNSSEC?
- Почему для работы TSIG обязательна синхронизация времени между серверами?
- Как реализуется split-horizon в BIND и почему важен порядок объявления views?
- Какой современный механизм заменил ручной auto-dnssec в BIND 9.18+ и в чём его удобство?