BIND9 на сервере: частые ошибки и решения
BIND9 — самый живучий DNS-сервер в индустрии: за десятилетия он оброс огромным числом параметров, и почти у каждого есть неочевидный побочный эффект. В логах при этом часто пишется что-то предельно скупое вроде «SERVFAIL» или «connection refused», а реальная причина спрятана на два уровня глубже. Разберём частые ошибки BIND9 на сервере по симптому, причине и решению с конкретными командами — от синтаксиса зоны до открытого резолвера.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Named не запускается: ошибка в конфиге или зоне
Классика: вы правите named.conf или файл зоны, перезапускаете сервис — и он не поднимается. systemctl status bind9 показывает failed, а сообщение об ошибке в одну строку не объясняет, что именно не так.
Первым делом проверяйте синтаксис до перезапуска, а не после — так вы вообще не увидите падения сервиса на проде.
named-checkconf /etc/bind/named.conf
named-checkzone example.com /etc/bind/db.example.com
journalctl -u bind9 -n 50 --no-pager
named-checkconf ловит структурные ошибки: пропущенную точку с запятой, незакрытую фигурную скобку, опечатку в имени параметра. named-checkzone отдельно проверяет файл зоны — это критично, потому что ошибка в зоне не всегда роняет весь сервис, а BIND просто откажется грузить конкретную зону и продолжит работать без неё, что заметить сложнее, чем полный краш. Самые частые проблемы в зонах — забытая точка в конце FQDN (www.example.com вместо www.example.com.), не увеличенный serial после правки (вторичные серверы просто не заметят изменений) и дублирующиеся записи. Если сервис не стартует, а checkconf и checkzone молчат, смотрите journalctl целиком: там часто указан конкретный номер строки и файл, где парсер споткнулся.
rndc: connection refused — управление сервером не работает
Вы пытаетесь выполнить rndc reload или rndc status, а в ответ — connection refused или unexpected end of input, хотя сам named при этом работает и резолвит нормально. Проблема не в самом DNS, а в отдельном управляющем канале между утилитой rndc и демоном named, который использует свой TSIG-ключ.
cat /etc/bind/rndc.key
grep -A3 controls /etc/bind/named.conf.options
rndc -s 127.0.0.1 -p 953 status
Чаще всего причина в рассинхроне ключа: файл rndc.key был перегенерирован (например, переустановкой пакета) или отредактирован вручную, а секция controls в named.conf.options ссылается на старый ключ или порт. Другой вариант — named.conf вообще не подключает rndc.key через include, и сервис слушает управляющий порт с ключом по умолчанию, которого нет у клиента. Пересоздать пару ключа можно командой rndc-confgen -a, она сама положит файл в /etc/bind/rndc.key с правильными правами — после этого достаточно systemctl restart bind9. Если управление нужно с другого хоста, а не только с локалхоста, отдельно проверьте, что controls { inet ... allow { ... }; } разрешает нужный адрес и что порт 953 не срезается фаерволом — если вы настраивали UFW, там нужно отдельное правило именно на 953/tcp.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверSERVFAIL и permission denied в логах
Домен резолвится с ошибкой SERVFAIL, а в логах — permission denied при попытке открыть файл зоны, хотя владелец файла вроде бы правильный. Это одна из самых обидных ошибок BIND9, потому что причина обычно вообще не в самом BIND, а в AppArmor или SELinux, которые ограничивают процесс named отдельным профилем безопасности поверх обычных прав файловой системы.
aa-status | grep named
ls -la /etc/bind/db.example.com
chown bind:bind /etc/bind/db.example.com
Если вы храните зоны не в стандартном /etc/bind или /var/cache/bind, а, скажем, в /opt/dns/zones, профиль AppArmor /etc/apparmor.d/usr.sbin.named просто не даёт named туда заглянуть — обычные Unix-права здесь не помогут, доступ режется на уровне LSM. Решение — либо держать зоны в стандартных путях, либо явно добавить новый путь в профиль AppArmor и перезагрузить его командой apparmor_parser -r /etc/apparmor.d/usr.sbin.named, либо временно перевести профиль в режим complain через aa-complain /usr/sbin/named, чтобы убедиться, что дело именно в этом (для постоянной эксплуатации это не решение, а только диагностика). Отдельно проверьте права на саму директорию, а не только на файл: BIND при обновлении зоны создаёт journal-файл .jnl рядом с зоной, и если директория не принадлежит пользователю bind, обновление зоны будет молча падать даже при верных правах на исходный файл.
Слейв не получает обновления зоны
На мастер-сервере вы поменяли записи и увеличили serial, а вторичный (слейв) DNS продолжает отдавать старые данные — иногда часами. Причин обычно три, и они легко проверяются по отдельности.
dig axfr example.com @master-ip
tail -f /var/log/syslog | grep named
rndc retransfer example.com
Первая причина — на мастере не разрешена передача зоны на IP слейва: параметр allow-transfer { slave-ip; }; внутри секции зоны или глобально в named.conf.options слишком узкий или вообще не задан (по умолчанию BIND в современных дистрибутивах передачу запрещает). Вторая — не настроен notify yes; на мастере, из-за чего слейв просто не узнаёт о том, что зону пора перетянуть, и ждёт истечения refresh-интервала из SOA-записи, который может быть выставлен на несколько часов. Третья, если используется TSIG — ключи для подписи трансфера на мастере и слейве не совпадают, и в логах будет tsig verify failure. Команда dig axfr с IP мастера, выполненная прямо со слейва, быстро покажет, доходит ли трансфер вообще и с какой ошибкой. Если конфигурация верна, а слейв всё равно не подтягивает данные, rndc retransfer example.com форсирует немедленную полную передачу зоны, не дожидаясь таймеров — удобно для диагностики, но не заменяет разбор первопричины.
DNSSEC: ошибки валидации и просроченные подписи
Домен с включённым DNSSEC внезапно перестаёт резолвиться у клиентов с валидирующими резолверами (тот же dnssec-validation auto;), хотя без DNSSEC всё работало. Классический признак — dig показывает флаг SERVFAIL вместе с bogus в статусе, а не просто пустой ответ.
dig +dnssec example.com A
delv example.com
named-checkzone -D example.com /etc/bind/db.example.com
Самая частая причина — истёкшие RRSIG-подписи: DNSSEC-подписи имеют срок годности, и если зона подписывается вручную скриптом по cron, а он перестал отрабатывать (сломался путь, истёк ключ, упало задание), валидирующие резолверы начинают браковать все ответы по зоне как «bogus», хотя сами данные корректны. Проверить срок действия подписи можно через delv, который явно покажет цепочку валидации и на каком шаге она рвётся. Решение для новых настроек — не подписывать зону вручную, а включить inline-signing yes; вместе с dnssec-policy в самом BIND: сервер сам следит за расписанием подписи и ключей, и это снимает всю ручную рутину. Если DNSSEC настроен недавно и ошибки появились сразу после включения — проверьте, что DS-запись в родительской зоне (у регистратора) действительно совпадает с текущим KSK, потому что рассинхрон между DS у регистратора и реальным ключом на сервере даёт точно такую же картину bogus-ответов.
Открытый резолвер: сервер отвечает на чужие рекурсивные запросы
Отдельная категория проблем — не «не работает», а «работает не так, как должно», и это опаснее. Если ваш BIND настроен как публичный авторитетный сервер для собственных доменов, но при этом отвечает рекурсией на запросы посторонних доменов от любого IP в интернете, сервер превращается в открытый резолвер — его используют для DNS-амплификации в чужих DDoS-атаках, а вы получаете аномальный трафик и жалобы от хостинга.
grep -A5 "options {" /etc/bind/named.conf.options
dig ANY isc.org @ваш-ip
Если такой запрос со стороннего адреса возвращает ответ вместо отказа, recursion открыта наружу. Для авторитетного сервера, который просто отдаёт свои зоны, правильная настройка — recursion no; в блоке options, тогда сервер вообще не будет пытаться резолвить чужие домены. Если рекурсия всё же нужна (например, сервер используется и как локальный резолвер для ваших же сервисов), ограничьте её через allow-recursion { localhost; localnets; ваша-подсеть; };, а лучше разделите роли через view: один view с recursion yes; только для доверенных сетей, второй, authoritative-only, для всех остальных. Фаервол здесь — вторая линия защиты, не первая: даже если UFW ограничивает доступ к 53-му порту, конфигурация BIND должна быть правильной сама по себе. Если с фаерволом на сервере пока не разобрались вообще, начните с базовой настройки UFW и разбора его частых ошибок — многие проблемы с DNS-безопасностью на практике решаются связкой из корректного named.conf и минимально закрытого фаервола.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Как безопасно проверить конфиг BIND перед перезапуском сервиса?
Выполните named-checkconf для основного файла и named-checkzone имя-зоны путь-к-файлу для каждой изменённой зоны до команды systemctl restart bind9 — так ошибка не уронит уже работающий сервис.
rndc пишет connection refused, хотя named запущен — что не так?
Обычно рассинхрон между ключом в /etc/bind/rndc.key и секцией controls в named.conf.options, либо файл ключа не подключён через include. Пересоздайте пару командой rndc-confgen -a и перезапустите сервис.
SERVFAIL и permission denied, хотя владелец файла зоны верный — в чём дело?
Скорее всего блокирует AppArmor: профиль /etc/apparmor.d/usr.sbin.named разрешает доступ только к стандартным путям вроде /etc/bind. Если зоны лежат в нестандартной директории, добавьте путь в профиль или переместите зоны.
Слейв не подтягивает новую версию зоны после правок на мастере — что проверить?
По порядку: allow-transfer на мастере для IP слейва, notify yes;, совпадение TSIG-ключей и увеличение serial в SOA. Команда dig axfr example.com @master-ip со слейва сразу покажет, доходит ли трансфер.
Как понять, что мой BIND — открытый резолвер и опасен для интернета?
Выполните dig ANY isc.org @ваш-ip с внешнего хоста, не входящего в ваши доверенные сети. Если приходит полноценный ответ вместо отказа — рекурсия открыта наружу, нужно recursion no; или ACL через allow-recursion.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →