DNS: зона BIND9 не завантажується — типові синтаксичні помилки й швидкі виправлення

Було корисно?

Коли зона BIND9 не завантажується, зона ураження рідко буває помірною. Половина сервісів «випадково» перестає працювати, хтось звинувачує мережу, а ваш телефон чергування починає поводитися якось по-особливому.

Добра новина: більшість простих інцидентів «зона не завантажується» викликані невеликим набором синтаксичних помилок, проблем з файлами/правами та кількома специфічними для BIND нюансами. Ще краща новина: ви можете швидко їх діагностувати, якщо припините гадати й почнете читати те, що вам каже named.

Швидкий план діагностики (перше/друге/третє)

Ця послідовність дозволяє найшвидше знайти вузьке місце. Вона орієнтована на продакшн-тріаж: отримаєте сигнал, зупиніть кровотечу, а потім доведіть до ладу.

Перше: підтвердьте, чи зона завантажена і яка версія активна

  • Запитайте у BIND, що він думає: rndc zonestatus та rndc status. Якщо BIND ніколи не завантажував зону, ви шукаєте проблему з файлом або синтаксисом, а не з кешуванням.
  • Опитайте сервер напряму: dig @127.0.0.1 для SOA та NS. Якщо ви отримуєте SERVFAIL або відсутній прапорець авторитетності, ви не обслуговуєте те, що думаєте.

Друге: прочитайте помилку, яку вже вивів BIND

  • Journald або syslog: journalctl -u named (або -u bind9) покаже точний збій парсингу, номер рядка і часто токен, який зламав файл.
  • Шукайте рядки «loading»: вам потрібні ім’я зони, шлях до файлу та причина. Якщо в логах написано «permission denied», не відкривайте Vim — виправляйте власника й SELinux/AppArmor.

Третє: перевірте офлайн за допомогою інструментів перевірки

  • named-checkconf: ловить проблеми на рівні конфігурації (неправильний view, дублікат зони, поганий синтаксис ACL, відсутній include).
  • named-checkzone: ловить синтаксичні проблеми в зоні (неправильні імена власників, зламана SOA, заборонені комбінації з CNAME, дані поза зоною).

Якщо в продакшні палає

  • Швидко відкотіть: відновіть останній відомо-рабочий файл зони, збільшіть серіал, перезавантажте. DNS — не місце для живого налагодження під галас Pager-а.
  • Зберігайте слід аудиту: скопіюйте зламану зону окремо, щоб потім вивчити її. Після інциденту ви не згадаєте, яка «дрібна зміна» спричинила все.

Що насправді означає «зона не завантажується» в BIND9

«Зона не завантажується» — це зручна спрощена фраза. У BIND9 це зазвичай означає одне з наступного:

  • BIND не може прочитати файл зони: неправильний шлях, права, SELinux/AppArmor, chroot-невідповідність або відсутній include-файл.
  • BIND може прочитати, але не може розпарсити: синтаксичні помилки, заборонені комбінації записів або зламані формати імен/TTL/класів.
  • BIND завантажив, але відхиляє: дані поза зоною, відсутні обов’язкові записи (SOA) або політики перевірки цілісності, особливо в новіших за замовчуванням або підсилених збірках.
  • BIND завантажив старішу версію, ніж ту, що ви редагували: ви змінили не той файл, не той view або зона генерується й перезаписується автоматизацією.
  • BIND завантажив зону, але клієнти все ще падають: бо зона завантажена, але неправильна — зламані делегації, відсутні NS, поганий glue, вайлдкард, який не працює, або проблеми з DNSSEC, що призводять до помилок перевірки.

Операційно ваша задача — за п’ять хвилин визначити, до якої з цих категорій належить помилка. Все інше — вправи для пальців.

Цікаві факти та контекст (бо DNS має історію)

  • BIND старший за більшість ваших інструментів: він виник в UC Berkeley у 1980-х і став фактичним DNS-сервером раннього інтернету.
  • Файли зон задумувалися як редаговані вручну: їхній покаратковий формат передує YAML, JSON і сучасним очікуванням суворих схем і дружніх парсерів.
  • Крапка в кінці — не прикраса: у DNS вона означає «абсолютне ім’я». Без крапки імена відносні до поточного origin, і так ви випадково створюєте ns1.example.com.example.com.
  • Серійні номери — це протокольний рукопотиск: серіал у SOA керує зональними трансферами (AXFR/IXFR). Погані серіали не лише нервують — вони залишають вторинні сервери на старих даних.
  • Негативне кешування — це фіча: RFC 2308 зробив NXDOMAIN кешованим з використанням SOA minimum/negative TTL. Ви можете «вирішити» запис, а помилки ще показуватимуться, поки кеш не пропаде.
  • TTL проектували для повільного світу: це грубий регулятор з часів, коли всі очікували, що кешування зекономить трафік і CPU.
  • DNSSEC зробив помилки голоснішими: без DNSSEC багато помилок перетворювалися на «неправильну відповідь». З DNSSEC вони можуть стати SERVFAIL у валідаційних резолверів.
  • Повідомлення про помилки BIND покращувалися з десятиліть: старі версії були криптичні; сучасний BIND зазвичай вказує номер рядка і токен. Просто люди не читають журналів.
  • Views ускладнюють розслідування: split-horizon DNS корисний, але також означає, що «зона в порядку» може бути правдою в одному view і неправдою в іншому.

Практичні завдання: команди, виводи та рішення (12+)

Це реальні команди, які ви можете виконати під час інциденту. Кожна включає що означає вивід і яке рішення прийняти далі.

Завдання 1: Перевірте здоров’я сервісу і яку unit-ім’я ви маєте

cr0x@server:~$ systemctl status bind9 --no-pager
● bind9.service - BIND Domain Name Server
     Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2025-12-31 08:10:22 UTC; 1h 12min ago
       Docs: man:named(8)
   Main PID: 1321 (named)
     Tasks: 12 (limit: 9456)
     Memory: 98.3M
     CGroup: /system.slice/bind9.service
             └─1321 /usr/sbin/named -f -u bind

Сенс: BIND запущений. «Зона не завантажується» — це не «демон впав».

Рішення: переходьте до логів і статусу зони; не витрачайте час на перезапуск, якщо тільки вам не потрібно примусово перезавантажити після виправлення.

Завдання 2: Витягніть останні помилки з journald

cr0x@server:~$ journalctl -u bind9 -n 60 --no-pager
Dec 31 09:14:02 server named[1321]: zone example.com/IN: loading from master file /etc/bind/zones/db.example.com failed: file not found
Dec 31 09:14:02 server named[1321]: zone example.com/IN: not loaded due to errors.
Dec 31 09:14:02 server named[1321]: managed-keys-zone: loaded serial 0

Сенс: Це не синтаксис. Це проблема шляху. BIND не може відкрити файл.

Рішення: перевірте stanza зони в named.conf і шлях у файловій системі; перевірте chroot та include-шляхи.

Завдання 3: Спочатку перевірте конфіг named (швидко, дешево, вирішально)

cr0x@server:~$ sudo named-checkconf -z
/etc/bind/named.conf.local:24: zone 'example.com': master file /etc/bind/zones/db.example.com: file not found

Сенс: Конфіг посилається на файл, якого немає в цьому місці.

Рішення: або виправіть шлях до файлу, або помістіть файл туди. Не редагуйте вміст зони поки не вирішите проблему з розташуванням.

Завдання 4: Підтвердіть, що файл існує там, де BIND очікує

cr0x@server:~$ ls -la /etc/bind/zones/db.example.com
ls: cannot access '/etc/bind/zones/db.example.com': No such file or directory

Сенс: Його справді там немає (або ви в неправильному root, якщо chroot).

Рішення: знайдіть фактичний файл, виправте деплой або оновіть stanza зони до правильного шляху.

Завдання 5: Знайдіть, де файл зони насправді лежить (часто в «дружній» автоматизації)

cr0x@server:~$ sudo find /etc/bind -maxdepth 3 -type f -name "db.example.com" -print
/etc/bind/master/db.example.com

Сенс: Хтось перемістив або згенерував файл в інший каталог.

Рішення: узгодьте конфіг і файлову систему. Краще посилатися в конфігу на фактичний керований шлях, ніж дублювати файли.

Завдання 6: Перевірте права та власність (BIND працює як користувач не випадково)

cr0x@server:~$ namei -l /etc/bind/master/db.example.com
f: /etc/bind/master/db.example.com
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root bind
drwx------ root root master
-rw-r----- root root db.example.com

Сенс: Каталог /etc/bind/master має режим 0700, тому користувач bind не може ним пройти.

Рішення: виправте права директорії (або перемістіть файл). Не «запускайте named як root», якщо вам не подобається писати звіти після інцидентів.

Завдання 7: Безпечно виправіть права і перезавантажте

cr0x@server:~$ sudo chgrp bind /etc/bind/master
cr0x@server:~$ sudo chmod 0750 /etc/bind/master
cr0x@server:~$ sudo chgrp bind /etc/bind/master/db.example.com
cr0x@server:~$ sudo chmod 0640 /etc/bind/master/db.example.com
cr0x@server:~$ sudo rndc reload example.com
server reload successful

Сенс: Reload пройшов успішно на рівні каналу керування. Це не гарантує, що зона завантажена; це означає, що BIND прийняв команду.

Рішення: підтвердіть статус зони і опитайте SOA/NS, щоб переконатися, що зона дійсно в пам’яті.

Завдання 8: Запитайте BIND напряму, чи зона завантажена

cr0x@server:~$ sudo rndc zonestatus example.com
name: example.com
type: master
files: /etc/bind/master/db.example.com
serial: 2025123101
nodes: 29
last loaded: Tue, 31 Dec 2025 09:22:11 GMT
secure: no

Сенс: Зона завантажена, і BIND використовує очікуваний файл із конкретним серіалом.

Рішення: переходьте до перевірок коректності (SOA/NS, glue, відповіді), а не до проблем парсера.

Завдання 9: Валідируйте файл зони офлайн перед тим, як торкатися продакшну знову

cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
zone example.com/IN: loaded serial 2025123101
OK

Сенс: Синтаксичні й базові семантичні перевірки пройдені.

Рішення: якщо клієнти все ще падають, дивіться делегацію, views, DNSSEC або кешування. Перестаньте звинувачувати парсер зони.

Завдання 10: Вловіть класичну «відсутню крапку» й конфуз origin з failing checkzone

cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
/etc/bind/master/db.example.com:18: NS 'ns1.example.com.example.com' has no address records (A or AAAA)
zone example.com/IN: loaded serial 2025123101
OK

Сенс: Зона завантажується, але BIND попереджає, що ваш NS ім’я було розширено відносно origin. Зазвичай це пропущена крапка в кінці FQDN.

Рішення: виправте ім’я NS (додайте крапку або використайте відносне ім’я свідомо) і переконайтеся, що для in-zone nameserver’ів є записи A/AAAA.

Завдання 11: Опитайте авторитетний сервер локально (виріжте кеш з історії)

cr0x@server:~$ dig @127.0.0.1 example.com SOA +norecurse

; <<>> DiG 9.18.24-1-Debian <<>> @127.0.0.1 example.com SOA +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; ANSWER SECTION:
example.com.  3600  IN  SOA  ns1.example.com. hostmaster.example.com. 2025123101 3600 900 1209600 300

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Dec 31 09:24:20 UTC 2025
;; MSG SIZE  rcvd: 98

Сенс: Авторитетна відповідь (aa) і коректні поля SOA. Зона обслуговується.

Рішення: якщо зовнішні клієнти бачать помилки, перевірте брандмауер/ACL, views або делегацію в батьківській зоні.

Завдання 12: Перевірте набір NS і очікування glue

cr0x@server:~$ dig @127.0.0.1 example.com NS +norecurse

; <<>> DiG 9.18.24-1-Debian <<>> @127.0.0.1 example.com NS +norecurse
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: NOERROR, id: 22222
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; ANSWER SECTION:
example.com.  3600  IN  NS  ns1.example.com.
example.com.  3600  IN  NS  ns2.example.com.

Сенс: Зона публікує два авторитетні сервери імен.

Рішення: переконайтеся, що імена NS розв’язуються. Якщо вони в зоні, опублікуйте glue A/AAAA у зоні. Якщо вони поза зоною — переконайтеся, що зовнішні імена доступні.

Завдання 13: Переконайтеся, що ви не створили заборонену суміш CNAME

cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
/etc/bind/master/db.example.com:42: 'www.example.com' CNAME and other data
zone example.com/IN: loading from master file /etc/bind/master/db.example.com failed: CNAME and other data
zone example.com/IN: not loaded due to errors.

Сенс: Один і той самий власник має CNAME і ще інші записи (A/AAAA/TXT/MX тощо). Це заборонено.

Рішення: оберіть: або CNAME, або «реальні» записи. Якщо потрібна поведінка типу apex, розгляньте ALIAS у провайдера (це не стандарт DNS) або переробіть архітектуру.

Завдання 14: Перевірте, чи не винні views

cr0x@server:~$ sudo named-checkconf -p | sed -n '1,120p'
acl "internal-nets" { 10.0.0.0/8; 192.168.0.0/16; };
view "internal" {
 match-clients { "internal-nets"; };
 zone "example.com" { type master; file "/etc/bind/master/db.example.com.internal"; };
};
view "external" {
 match-clients { any; };
 zone "example.com" { type master; file "/etc/bind/master/db.example.com.external"; };
};

Сенс: Два різні файли обслуговують ту саму зону залежно від джерела клієнта.

Рішення: переконайтеся, що ви відредагували правильний файл для проблемних клієнтів. «Працює на моєму ноуті» часто означає «працює у внутрішньому view».

Завдання 15: Провалідуйте файли, пов’язані з DNSSEC, якщо зона підписана

cr0x@server:~$ journalctl -u bind9 -n 30 --no-pager
Dec 31 09:30:11 server named[1321]: zone example.com/IN: loaded serial 2025123101
Dec 31 09:30:11 server named[1321]: zone example.com/IN: signing with keys in key repository
Dec 31 09:30:11 server named[1321]: zone example.com/IN: DNSKEY RRset is not signed
Dec 31 09:30:11 server named[1321]: zone example.com/IN: not loaded due to errors.

Сенс: У вас є очікування щодо DNSSEC (inline-signing або політики), але дані зони/ключі не відповідають їм.

Рішення: визначте, чи DNSSEC обов’язковий для цієї зони. Якщо так — виправте ключі/політи та повторно підпишіть. Якщо ні — тимчасово вимкніть функції DNSSEC для зони, щоб відновити сервіс.

Завдання 16: Підтвердіть, що бачить зовнішній світ (авторитетні відповіді, не кеш)

cr0x@server:~$ dig @ns1.example.com example.com SOA +norecurse

; <<>> DiG 9.18.24 <<>> @ns1.example.com example.com SOA +norecurse
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: SERVFAIL, id: 33333
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

Сенс: Авторитетний сервер повертає SERVFAIL. Зазвичай це проблема на стороні сервера (зона не завантажена, поломка DNSSEC, runtime-помилки), а не кеш клієнта.

Рішення: повертайтеся до логів сервера і статусу зони; не витрачайте час на очищення резолверів.

Жарт №1: DNS — єдина система, де додавання крапки може полагодити продакшн. У більшості інших місць додавання розділових знаків просто породжує Slack-драму.

Поширені помилки: симптом → корінь → виправлення

Цей розділ навмисно конкретний. Якщо вам потрібні загальні поради — є багато блогів, що це роблять погано.

1) Симптом: «zone not loaded due to errors» після reload

Корінь: Ви повірили rndc reload, що він скаже вам, що зона завантажена. Він лише повідомляє, що команда прийнята.

Виправлення: Завжди слідуйте rndc zonestatus example.com та named-checkzone. Якщо виникає помилка, ви отримаєте точний parse error і номер рядка.

2) Симптом: «file not found», але ви клянетесь, що файл існує

Корінь: Неправильний шлях у stanza зони, невідповідність include або ви запускаєте BIND у chroot і дивитесь на хост-файлову систему, а не на джейл.

Виправлення: Використайте named-checkconf -z, щоб побачити, що BIND намагається відкрити. Якщо chroot, перевірте, що файл існує під chroot-каталогом. Підтвердіть за допомогою ls -la всередині того кореня.

3) Симптом: «permission denied» при завантаженні файлу зони

Корінь: Відсутні права проходження директоріями (схований винуватець), неправильна власність або блокування політики MAC (SELinux/AppArmor).

Виправлення: Запустіть namei -l /path/to/zone. Виправте біти режиму директорій так, щоб користувач BIND міг пройти. Якщо SELinux — перевірте AVC denials і виставте правильний контекст.

4) Симптом: «CNAME and other data»

Корінь: Ім’я одночасно має CNAME і інші RRset (A/AAAA/TXT/MX/NS і т.д.). Часто трапляється, коли хочуть, щоб www вказував кудись, але одночасно лишають TXT для верифікації.

Виправлення: Видаліть конфліктні записи. Якщо потрібен TXT на тому самому імені — не використовуйте там CNAME. Використайте A/AAAA або перенесіть верифікацію на інший лейбл.

5) Симптом: «out of zone data»

Корінь: Ви помістили записи для іншого домену у файл (часто через відсутні крапки-термінатори або вставку з іншої зони).

Виправлення: Переконайтеся, що імена власників належать до origin зони. Обережно використовуйте $ORIGIN. Додавайте крапки в кінці абсолютних імен.

6) Симптом: Зона завантажується, але вторинники ніколи не оновлюються

Корінь: Серіал SOA не змінився або пішов назад (серіальний формат на основі дати з помилкою), або ви редагували неправильний view/файл зони.

Виправлення: Підніміть серіал вперед. Використовуйте монотонну схему. Потім rndc notify example.com і перевірте логи трансферів на вторинниках.

7) Симптом: NXDOMAIN зберігається після того, як ви «виправили» запис

Корінь: Негативне кешування відповідно до SOA minimum/negative TTL. Також можливо: ви змінили внутрішній view, а клієнти запитують зовнішній.

Виправлення: Перевірте поле minimum у SOA; зменшіть його перед змінами при плануванні міграцій. Перевірте, який view відповідає вашому тестовому клієнту, опитуючи з того самого мережевого шляху.

8) Симптом: «bad owner name (check-names)»

Корінь: Заборонені символи в іменах власників (підкреслення в хостнеймах, пробіли тощо) або суворі налаштування перевірки.

Виправлення: Виправте ім’я. Підкреслення дозволені в певних контекстах записів (наприклад SRV), але не як загальні імена хостів. Не «виправляйте» відключенням перевірок глобально, якщо ви не любите приховані помилки.

9) Симптом: Зона завантажується локально, але зовнішні резолвери отримують SERVFAIL

Корінь: Помилки валідації DNSSEC (просрочені підписи, відсутній DS, неправильний стан NSEC/NSEC3), «lame» делегація або блокування TCP/UDP 53 брандмауером.

Виправлення: Підтвердіть авторитетність з кількох точок. Перевірте стан ланцюга DNSSEC і свіжість підписів. Переконайтеся, що TCP 53 працює (великі відповіді з DNSSEC часто потребують його).

10) Симптом: «unexpected end of input» / парсер обривається посеред файлу

Корінь: Відсутня закриваюча дужка в багаторядковому SOA, незакриті лапки в TXT або вставлення, яке обірвало останній рядок чи дужки.

Виправлення: Запустіть named-checkzone і перейдіть до номера рядка. Потім проскануйте вгору на предмет незакритих конструкцій; парсер часто показує місце, де помітив проблему, а не де вона почалася.

11) Симптом: Попередження «ignoring out-of-zone data» і відсутні записи

Корінь: Ім’я власника розширилося в неправильне ім’я через відносні лейбли і зміни $ORIGIN.

Виправлення: Будьте явні: використовуйте повні імена з крапками в кінці для всього, що не під поточним origin, і уникайте частих змін $ORIGIN, якщо зона не надто складна.

12) Симптом: Reload працює, але відповіді все ще старі

Корінь: Ви редагували файл, який BIND не використовує (неправильний view, неправильний include, згенерований файл перезаписується). Або BIND відмовився завантажити нову версію і тримає стару в пам’яті.

Виправлення: rndc zonestatus, щоб побачити шлях до файлу і серіал, який наразі завантажено. Порівняйте з тим, що ви редагували. Якщо невідповідність — виправляйте процес деплою/автоматизацію, а не синтаксис зони.

Три корпоративні міні-історії з практики

Міні-історія 1: Інцидент через хибне припущення

Команда мігрувала клієнтський додаток між балансувальниками. План був простий: додати новий запис A, тримати низький TTL і переключити трафік оновленням одного імені. Вони відредагували зону, підняли серіал, виконали rndc reload і спостерігали за синтетичними перевірками. Все зелено.

Потім почалися дзвінки. Зовнішні користувачі не могли розв’язати ім’я; внутрішні могли. Перше припущення було передбачуваним: «публічний DNS кешує стару відповідь». Хтось запропонував очищати кеші (завжди мило), інший радив почекати.

Справжня проблема була в split-horizon DNS. Було два views: internal і external. Інженер оновив internal-файл, бо саме на нього потрапляв їхній ноут через VPN. External view все ще вказував на старий балансувальник, який уже був напіввиведений з обслуговування. У їхній ментальній моделі була «зона». У BIND — дві зони з однаковим іменем.

Виправлення технічно було тривіальним — оновити правильний файл, підняти серіал, перезавантажити. Важче було пояснити, чому в тесті все працювало, а для клієнтів — ні. Урок запам’ятався: завжди тестуйте з точки зору клієнта, який вам важливий. Для DNS це означає опитувати авторитетний сервер з потрібної мережі і перевіряти, в який view ви опинилися.

Після інциденту вони додали у рукопис крок: named-checkconf -p для друку активної конфігурації і пару dig-команд, що виконуються з внутрішньої машини та зовнішньої перспективи. Це запобігло наступній «але в мене працює» паніці.

Міні-історія 2: Оптимізація, що підвела

Платформна група вирішила, що файли зон «занадто повільно» перезавантажуються, і впровадила оптимізацію: генерувати їх із агресивними $ORIGIN-змінами і опускати «непотрібні» крапки в кінці, щоб зменшити розмір файлу й зробити шаблони компактнішими. Також вони ввели include-композицію, щоб кілька команд могли додавати фрагменти.

Результат — файл зони, що здавався елегантним для людей, які вже знали його логіку — і незрозумілим під час інцидентів. Одна пропущена крапка в NS-мішені тихо розширилася в неправильне ім’я, і оскільки воно було поза зоною, у нього не було адресних записів. Деякі резолвери це терпіли, інші — ні. До того ж include-шляхи відрізнялися між середовищами. Staging завантажувався; production падав з file-not-found через іншу структуру директорій.

Аут — неприємні, але не драматичні помилки: періодичні проблеми резолюції і спорадичні таймаути. Запити переходили між мережею, SRE і командами додатків, бо ніхто не бачив чистого стану «down». Логи BIND містили попередження, але ніхто їх не читав, бо «попередження — це нормально».

Виправлення було нудним і ефективним: припинити хитрувати. Вони стандартизували явні FQDN з крапками для всього, що не було явно відносним, зменшили використання $ORIGIN і зробили генератор, який продукував один канонічний файл на зону на view. Файл став більшим. Час перезавантаження не мав значення. Середній час на розуміння проблеми значно скоротився.

Жарт №2: Якщо ваш DNS-файл потребує генератора, щоб бути читабельним, ви не створили автоматизацію — ви створили загадку.

Міні-історія 3: Нудна, але правильна практика, яка врятувала день

Регульована організація мала правило зміни: кожне редагування DNS має проходити named-checkzone та named-checkconf в CI, і система деплою відмовлялася публікувати файли, які не валідні. Інженери бурчали. Звісно, бурчали.

Одного п’ятничного ранку звичайна зміна додала TXT-запис для верифікації домену. Інженер випадково розмістив TXT на імені, яке вже мало CNAME (бо маркетинг хотів «красиві імена»). У менш формальному середовищі зона б впала і забрала з собою купу не споріднених записів — бо зона атомарна з точки зору BIND.

Натомість CI заблокував коміт з чіткою помилкою «CNAME and other data», включно з точним номером рядка. Вони виправили, перенесли верифікацію на інший лейбл і безпечно випустили. Ніхто не отримав сповіщення. В понеділок ніхто й не згадав.

Практика була непомітною: перевіряти перед reload, деплоїти з одного джерела істини і логувати зміни серіалів. Це не інновація, але це спосіб не пояснювати керівництву, чому «TXT-запис» спричинив інцидент.

Контрольні списки / покроковий план

Чекліст інциденту: зона зараз не завантажується

  1. Підтвердіть вплив: це одне ім’я, одна зона чи всі зони? Опитайте SOA/NS локально і принаймні з однієї зовнішньої точки.
  2. Перевірте здоров’я BIND: сервіс запущений, CPU/пам’ять в нормі, немає циклів краху.
  3. Прочитайте останні 100 рядків логів: знайдіть першу помилку для спроби завантаження зони; не гоніться за шумом наслідків.
  4. Запустіть named-checkconf -z: виправте відсутні include, погані шляхи файлів, дублікати зон, проблеми з view.
  5. Запустіть named-checkzone: виправте синтаксичні помилки, конфлікти CNAME, формат SOA, імена власників, дані поза зоною.
  6. Виправте доступ до файлової системи: права, власність, SELinux/AppArmor. Перевірте за допомогою namei -l.
  7. Перезавантажте й перевірте: rndc reload zone, потім rndc zonestatus, потім dig @127.0.0.1 SOA/NS.
  8. Якщо все ще падає зовні: перевірте views, брандмауер, делегацію, стан DNSSEC.

Чекліст змін: безпечно редагувати зону (щоб не дзвонив Pager)

  1. Визначте вікно зміни залежно від TTL: якщо потрібен швидкий rollout/rollback — заздалегідь знизьте TTL.
  2. Редагуйте з запобіжниками: використовуйте лінтер або принаймні послідовне форматування. Багаторядковий SOA — нормально; лише тримайте дужки збалансованими.
  3. Завжди піднімайте серіал SOA: і переконайтеся, що він монотонно зростає у всіх шляхах деплою.
  4. Перевіряйте офлайн: named-checkzone для файлу зони, named-checkconf якщо ви змінювали include/view.
  5. Перезавантажуйте цілеспрямовано: rndc reload example.com, а не перезапускайте все.
  6. Перевіряйте авторитетні відповіді: опитайте сервер напряму для SOA/NS і зміненого імені. Підтвердіть прапорець aa.
  7. Перевірте трансфери/пропагацію: якщо є вторинники — переконайтеся, що вони підтягли новий серіал.
  8. Запишіть, що ви змінили: однорядковий опис у тікеті. Минуле-ви — незнайомець з меншим сном.

Чекліст підсилення: зробіть так, щоб помилки завантаження зон були рідкісними й короткими

  • Валідація в CI: блокуйте мерджі, які не проходять named-checkzone/named-checkconf.
  • Єдине джерело істини: генеруйте один канонічний файл на зону/view і деплойте атомарно.
  • Логуйте серіали: ставтеся до змін серіалу як до версії релізу.
  • Розділяйте обов’язки: не змішуйте ручні правки з згенерованими фрагментами, якщо любите детективні історії.
  • Використовуйте вторинники: і тестуйте їх. Хороший secondary — страховка і моніторинговий інструмент.
  • Алерт на «zone not loaded»: збирайте логи або використовуйте перевірки на базі rndc.

Питання та відповіді

1) Чому rndc reload каже «successful», коли зона все ще не завантажена?

rndc повідомляє, що BIND прийняв команду керування, а не те, що парсинг пройшов успішно. Завжди перевіряйте rndc zonestatus і логи.

2) Який найшвидший спосіб знайти точний рядок синтаксичної помилки?

Запустіть named-checkzone example.com /path/to/zone. Воно виведе файл і номер рядка, зазвичай із проблемним токеном.

3) Я виправив запис, але клієнти все ще бачать NXDOMAIN. BIND зламався?

Ймовірно, ні. NXDOMAIN кешується (негативне кешування). Перевірте minimum/negative TTL у SOA і зачекайте або плануйте заздалегідь, знижуючи його перед змінами.

4) Чи справді потрібна крапка в кінці FQDN у файлах зон?

Якщо ви хочете абсолютне ім’я — так. Без крапки BIND трактує ім’я як відносне до поточного origin. Саме так виникає абсурд типу ns1.example.com.example.com.

5) Чи можу я мати CNAME і TXT на тому самому імені?

Ні. CNAME не може співіснувати з іншими даними на тому самому імені. Перенесіть TXT на інший лейбл або не використовуйте CNAME.

6) Чому вторинники не підтягнули зміни, хоча primary їх віддає?

Найчастіше серіал SOA не збільшився. Вторинники порівнюють серіали; якщо він незмінний (або менший), вони залишають стару зону.

7) Зона завантажується, але зовнішні резолвери отримують SERVFAIL. Що далі?

Спочатку перевірте DNSSEC, якщо ви його використовуєте. Також перевірте доступність TCP/53 і коректність делегації. SERVFAIL від авторитетного сервера — серйозний сигнал.

8) Як views ускладнюють розслідування?

Вони створюють кілька версій «однієї» зони. Ви маєте підтвердити, до якого view належить клієнт, і валідовати відповідний файл зони.

9) Який безпечний формат серіалу SOA?

Формат на основі дати YYYYMMDDnn працює, якщо ви ніколи не повертаєтесь назад. Також підходить монотонне ціле число. Виберіть одне й вимагайте його у інструментах.

10) Чи варто вимикати check-names, щоб прибрати попередження?

Зазвичай ні. Виправте імена. Вимикання перевірок сьогодні міняє явне попередження на заплутану помилку пізніше.

Практичні наступні кроки

Коли BIND9 не завантажує зону, не «перезавантажуй усе» як звичку. Зробіть дисципліновано:

  1. Запитайте у BIND, що він завантажив: rndc zonestatus і опитайте SOA/NS напряму.
  2. Читайте логи уважно, ніби вони вам платять (так і є).
  3. Валідуйте офлайн за допомогою named-checkconf і named-checkzone перед тим, як знову торкатися продакшну.
  4. Почніть з нудних речей: шляхи, права й крапки в кінці.
  5. Інституціоналізуйте перемогу: додайте CI-перевірки й чекліст розгортання, щоб це стало не подією.

І ще один надійний девопс-маніфест, перефразована ідея від W. Edwards Deming: якість приходить від покращення процесу, а не від звинувачень людей. DNS-інциденти люблять слабкі процеси.

← Попередня
Ubuntu 24.04 systemd unit overrides: виправляйте сервіси чисто, не редагуючи файли постачальника (випадок №8)
Наступна →
Чому оновлення мікрокоду стануть такими ж звичними, як оновлення драйверів

Залишити коментар