Перейти до вмісту

DNS

Сайт не відкривається, а ping 192.0.2.10 проходить. Або інакше: ви перенесли сайт на новий сервер, змінили запис, а половина користувачів ще годину ходить на старий. Або: у контейнері curl чекає п’ять секунд, перш ніж з’єднається, і жодних помилок у лозі нема.

Усі ці історії про одну систему, і в ІТ про неї є приказка: «це завжди DNS». Жарт тримається на тому, що DNS стоїть перед майже кожним з’єднанням, кешується на п’яти рівнях і збоїть мовчки. Після цього модуля ви зможете показати, на якому саме кроці розв’язання зупиняється ім’я, і пояснити, чому інша людина бачить іншу відповідь.

Передумови. UDP, TCP і порти (модуль 11), адреси (модуль 6). Вміти запустити dig (пакет bind9-dnsutils у Debian і Ubuntu, bind-utils у сімействі Red Hat).

Навіщо імена і як їх колись розв’язували

Section titled “Навіщо імена і як їх колись розв’язували”

Люди запам’ятовують імена, а маршрутизатори працюють з адресами. Потрібна таблиця відповідності, і в ранній мережі вона була буквально таблицею: один файл HOSTS.TXT, який вів єдиний центр, а всі вузли періодично його завантажували. Поки вузлів були сотні, це працювало. Коли їх стало тисячі, файл розрісся, його доводилося скрізь оновлювати, а змінити навіть один рядок міг лише центр.

DNS, запропонований на початку 1980-х, розв’язав це не кращим файлом, а іншою будовою: розподіленою базою з делегуванням. Кожен власник домену сам тримає свою частину даних, а щоб знайти чужу, ніхто не мусить мати копію всього. Ця ідея (ієрархія, кеш, делегування) працює понад сорок років.

Файл теж нікуди не подівся: /etc/hosts живий досі й, як побачимо, має пріоритет.

Ієрархія і делегування

Section titled “Ієрархія і делегування”

Ім’я читається справа наліво. У www.example.com. кінцева крапка позначає корінь, далі com, далі example, далі www. Кожен шматок між крапками називається міткою (label). Мітка може мати до 63 байтів, а все ім’я в текстовому вигляді не довше за 253 символи.

Це дерево, і кожна його гілка може належати іншій організації.

  • Корінь (root) — вершина. За ним стоять 13 імен серверів (від a.root-servers.net до m.root-servers.net), але це лише імена: кожне обслуговують багато фізичних серверів у різних країнах за однією адресою (anycast).
  • Домени верхнього рівня (TLD): com, org, ua, de. Їх утримують реєстри.
  • Домени нижче: example.com належить тому, хто його зареєстрував, і він сам вирішує, що лежить усередині.

Домен і зону (zone) легко сплутати. Домен охоплює піддерево імен, а зона — лише ту частину дерева, що описана в одному файлі даних і обслуговується одними серверами. Коли власник example.com вирішує віддати dev.example.com іншій команді, він делегує піддомен: додає у свою зону записи NS, які кажуть, «за цим піддеревом іди до таких-то серверів». Відтепер dev.example.com — окрема зона, а батьківська її вміст не знає.

Записи NS у батьківській зоні іноді потребують ще й адреси: якщо сервери dev.example.com самі називаються ns1.dev.example.com, то, щоб їх знайти, треба спершу знайти їх ім’я, а для цього вже треба сервер. Вирішує це glue-запис: у батьківській зоні поруч із NS лежить і адреса, яку віддають у відповіді як «додаткову».

Сервер, що відповідає за зону зі своїх даних, називається авторитетним (authoritative). У його відповіді стоїть прапорець aa. Достеменно відповідь знає лише він, решта тільки кешує чи переказує.

Хто бере участь у запиті

Section titled “Хто бере участь у запиті”

У розв’язанні імені задіяні різні ролі, і їх часто плутають.

  • Stub-резолвер живе у вашій програмі чи ОС як крихітна частина бібліотеки. Він не вміє ходити ієрархією, лише спитати одного знайомого сервера і прийняти відповідь. Адреса цього сервера записана в /etc/resolv.conf.
  • Рекурсивний резолвер (recursive resolver) бере на себе всю роботу: ходить від кореня вниз, збирає відповідь, кешує й віддає її клієнту. Його тримають провайдер, організація або публічний сервіс, а на домашньому роутері це зазвичай пересилач до провайдерського.
  • Авторитетний сервер — остаточне джерело для своєї зони. Сам нікуди не ходить і кешем не користується.

Для кожної ролі є свої програми: Unbound і Knot Resolver рекурсивні, NSD і Knot DNS авторитетні, а BIND уміє обидві. Поєднувати їх на одному публічному сервері не радять: рекурсія, відкрита для всього інтернету, стає знаряддям DDoS-підсилення. Авторитетний сервер має відповідати лише про свою зону й нікому не робити рекурсію.

Рекурсивне розв’язання імені www.example.com: stub-резолвер питає рекурсивний резолвер, той по черзі корінь, сервер .com і авторитетний сервер example.comstubваш застосунокрекурсивнийрезолверкорінь.TLD.comавторитетнийexample.com1 www.example.com A?2 www.example.com A?3 не знаю, питай .com4 www.example.com A?5 не знаю, питай example.com6 www.example.com A?7 A 192.0.2.10, TTL (aa)8 A 192.0.2.10 (кеш)з теплим кешем кроки 2–7 зникають: резолвер відповідає сам
Розв'язання з порожнім кешем. Резолвер сам іде вниз по ієрархії, а кожен сервер по дорозі відповідає «не знаю, але спитай он тих» і віддає їхні NS та адреси. Лише авторитетний сервер дає саму відповідь, зі своїм TTL.

Одне ім’я з порожнім кешем коштує чотирьох обмінів по мережі. Кеш у DNS — умова існування, а не оптимізація: без нього корінь утонув би за першу хвилину. З теплим кешем про корінь і com резолвер майже ніколи не питає, бо їхні NS живуть у кеші добу й довше.

Повідомлення і транспорт

Section titled “Повідомлення і транспорт”

Запит і відповідь мають однаковий формат: заголовок, питання (ім’я, тип, клас), а далі три секції записів: відповідь, авторитетні (authority) і додаткові (additional). У заголовку найцікавіші прапорці:

Прапорець Значення
qr це відповідь, а не запит
aa відповідає авторитетний сервер
rd клієнт просить рекурсію (recursion desired)
ra сервер її підтримує (recursion available)
tc відповідь обрізана й не влізла в датаграму
ad дані перевірено через DNSSEC

і код результату RCODE: NOERROR (усе гаразд), NXDOMAIN (такого імені немає), SERVFAIL (сервер не зміг відповісти: недоступні авторитетні, збій перевірки підпису), REFUSED (сервер не хоче відповідати саме вам).

Окремий випадок: NOERROR з порожньою секцією відповіді. Ім’я існує, але запису запитаного типу нема (наприклад, AAAA для хоста, що має тільки A). Це NODATA, і це не NXDOMAIN.

Транспорт. Звичайний запит іде за UDP на порт 53: одна датаграма туди, одна назад, без рукостискання (тому DNS і було створено на UDP, див. модуль 11). Якщо відповідь не влізла, сервер ставить прапорець tc і відправляє скільки влізло. Клієнт, побачивши tc, повторює запит за TCP на той самий порт. Це легко побачити, якщо змусити сервер віддати велику відповідь і вимкнути розширення, що збільшує ліміт (+noedns: тоді ліміт класичні 512 байтів):

Terminal window
dig @10.0.0.13 big.example.test TXT +noedns +ignore | grep flags
dig @10.0.0.13 big.example.test TXT +noedns | grep -E "SERVER|MSG SIZE"
;; flags: qr aa tc rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; SERVER: 10.0.0.13#53(10.0.0.13) (TCP)
;; MSG SIZE rcvd: 850

Перша команда з +ignore не повторює запит і показує tc. Друга повторює сама, і видно, що справжню відповідь (850 байтів) отримано вже за TCP. Сучасні клієнти за замовчуванням користуються механізмом EDNS0, який дозволяє оголосити більший розмір UDP-датаграми (у повному виводі dig це рядок EDNS: ... udp: 1232), тому tc трапляється рідше, але не зник. Так само за TCP ходять перенесення зон між серверами й великі відповіді з DNSSEC.

Файрвол, який пропускає лише UDP 53 і блокує TCP 53, зламає DNS вибірково, лише для великих відповідей. Діагностувати таке важко: більшість запитів працює.

Кожен запис у відповіді несе TTL (time to live), число секунд, протягом яких його дозволено тримати в кеші. Резолвер відраховує його вниз, і це видно на власні очі: перший запит до резолвера дає 300, другий через три секунди — 297.

Terminal window
dig @127.0.0.1 www.example.test
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
www.example.test. 300 IN CNAME web.example.test.
web.example.test. 300 IN A 192.0.2.10
web.example.test. 300 IN A 192.0.2.11
# повторний запит через 3 секунди:
www.example.test. 297 IN CNAME web.example.test.
web.example.test. 297 IN A 192.0.2.11
web.example.test. 297 IN A 192.0.2.10

Прапорця aa немає, бо відповідь прийшла з кешу резолвера. А порядок адрес змінився: сервер навмисно ротує записи, що дає найпростіший розподіл навантаження (DNS round-robin).

З цього випливає головна властивість DNS: зміна запису не діє, доки не скінчиться TTL у чужих кешах. Експеримент: запис із TTL 5 секунд, який змінюють на авторитетному сервері.

резолвер, до зміни: fast.example.test. 5 IN A 192.0.2.50
авторитетний, після зміни: 192.0.2.51
резолвер, одразу після: fast.example.test. 2 IN A 192.0.2.50 ← старе
резолвер, за 5 с: fast.example.test. 5 IN A 192.0.2.51 ← нове

Автор запису не може «скасувати» те, що вже лежить у чужих кешах, тож перед плановим перенесенням сайту TTL зменшують (скажімо, до хвилини) заздалегідь, щонайменше на стару величину TTL раніше, і підіймають назад після. Навпаки, TTL у добу означає, що помилку в записі виправлятимуть добу.

Кешується й відсутність відповіді: інакше кожен запит до неіснуючого імені доходив би до авторитетного сервера. Тривалість негативного кешу береться із запису SOA зони: менше з TTL самого SOA і його останнього поля (minimum). Зона example.test у нашому експерименті має SOA з TTL 300 і minimum 60:

example.test. 60 IN SOA ns1.example.test. hostmaster.example.test. 2026093001 3600 600 86400 60

Резолвер віддав відповідь NXDOMAIN із SOA у секції authority і TTL 60, а за дві секунди повторив її з TTL 58. Звідси знайома ситуація: створили запис для щойно вигаданого імені, відкрили сторінку, побачили помилку, додали запис, а помилка не зникає ще хвилину (чи годину, залежно від minimum), бо в кеші лежить «нема».

Поля SOA загалом: головний сервер зони, пошта відповідального (першу крапку читають як @), серійний номер (його збільшують за кожної зміни, щоб вторинні сервери помітили), інтервали оновлення, повтору й закінчення для вторинних серверів і те саме minimum.

Між вами і авторитетним сервером кешують майже всі: браузер, бібліотека в процесі, локальна служба на кшталт systemd-resolved, роутер, рекурсивний резолвер провайдера. Тому колеги й бачать інакше, ніж ви: у кожного своя гілка кешів із власною датою народження. Командою dig зі вказаним сервером (@адреса) ви обходите всі локальні шари і питаєте саме цей рівень.

Запис складається з імені, TTL, класу (завжди IN), типу й даних. Типи, що траплятимуться найчастіше:

Тип Що містить Приклад
A IPv4-адреса web A 192.0.2.10
AAAA IPv6-адреса web AAAA 2001:db8::10
CNAME псевдонім, інше ім’я www CNAME web
MX поштовий сервер і пріоритет (менше — важливіше) @ MX 10 mail
NS авторитетний сервер зони чи делегування @ NS ns1
SOA службові параметри зони див. вище
TXT довільний текст: SPF, підтвердження власності @ TXT "v=spf1 -all"
PTR ім’я за адресою, зворотне розв’язання 10.2.0.192.in-addr.arpa. PTR web.example.test.
SRV хост і порт сервісу, пріоритет, вага _sip._tcp SRV 10 5 5060 sip
CAA які центри сертифікації можуть видавати сертифікат для домену @ CAA 0 issue "letsencrypt.org"

Запуск dig з типом після імені показує кожен із них. Вивід із нашої лабораторної зони:

example.test. 300 IN MX 10 mail.example.test.
example.test. 300 IN TXT "v=spf1 -all"
example.test. 300 IN CAA 0 issue "letsencrypt.org"
_sip._tcp.example.test. 300 IN SRV 10 5 5060 sip.example.test.
10.2.0.192.in-addr.arpa. 300 IN PTR web.example.test.

Кілька правил, об які спотикаються першими.

  • CNAME — це не перенаправлення, а синонім. Ім’я з CNAME не може мати жодних інших записів, тому CNAME не ставлять на вершині зони (example.com сам мусить мати NS і SOA). Резолвер бачить CNAME, далі розв’язує цільове ім’я і віддає ланцюжок, як у виводі вище.
  • PTR — у власному дереві. Адреса 192.0.2.10 записується задом наперед як 10.2.0.192.in-addr.arpa. Власник блоку адрес (провайдер) делегує зворотну зону тому, кому віддав адреси. Тому PTR часто відсутній або не збігається з A.
  • MX вказує на ім’я, не на адресу, і те ім’я не може бути CNAME.
  • SRV дозволяє не вшивати порт у клієнта. Клієнт питає _sip._tcp.домен і отримує хост, порт і пріоритет. Ім’я починається з підкреслень, бо це службові мітки.

Як застосунок розв’язує ім’я

Section titled “Як застосунок розв’язує ім’я”

Програма розв’язує ім’я викликом getaddrinfo() з бібліотеки C. Той спершу звіряється зі списком у /etc/nsswitch.conf:

hosts: files dns

Спершу files (/etc/hosts), тоді dns. Тому запис у /etc/hosts завжди виграє і є найзручнішим способом «підмінити» ім’я локально для перевірки. Але тут же й пастка:

Terminal window
getent hosts pinned.example.test # іде за nsswitch: знайде в /etc/hosts
dig pinned.example.test +short # питає лише DNS: нічого
192.0.2.77 pinned.example.test
(порожньо)

dig не користується nsswitch.conf і /etc/hosts. Якщо ping бачить ім’я, а dig ні (чи навпаки), причина майже завжди тут. Щоб побачити те, що бачить програма, користуйтеся getent hosts.

Другий файл — /etc/resolv.conf, де записано, кого питати:

nameserver 127.0.0.1
search example.test
options timeout:2 attempts:2
  • nameserver — адреса рекурсивного резолвера (використовуються перші три); якщо перший мовчить, бібліотека чекає timeout (за замовчуванням 5 с) і пробує наступний, звідси ті самі «п’ять секунд перед з’єднанням».
  • search — домени, які дописуються до неповного імені. Тому getent hosts web знайде web.example.test, а dig web без +search питає про web. і отримує NXDOMAIN.
  • options ndots:N — скільки крапок має мати ім’я, щоб його спершу спробували як повне, а вже потім із search. У контейнерних середовищах туди часто ставлять ndots:5, і тоді розв’язання короткого зовнішнього імені проходить кілька марних запитів із доданими доменами, перш ніж дійде до справжнього.

Класичний DNS не має ні автентичності, ні таємності. Відповідь можна підробити на шляху або отруїти кеш резолвера (знаменита атака Дена Камінськи 2008 року), а запити видно кожному, хто бачить трафік. Ці дірки закривають окремі інструменти.

DNSSEC відповідає за автентичність. Власник зони підписує свої записи ключем, і підпис лежить поруч у записах RRSIG, а відкритий ключ у DNSKEY. Довіряти ключу зони можна тому, що батьківська зона публікує його хеш у записі DS, а батьківську перевірено так само вище, аж до кореня, чий ключ резолвер знає заздалегідь. Це ланцюг довіри, що йде вниз по тій самій ієрархії делегування. Валідуючий резолвер перевіряє ланцюг і ставить у відповіді ad; якщо підпис не сходиться, клієнт отримує SERVFAIL. DNSSEC не шифрує нічого: запити й відповіді лишаються відкритими, а гарантовано лише те, що їх не підмінили.

DoT (DNS over TLS) і DoH (DNS over HTTPS) відповідають за таємність на ділянці клієнт → резолвер. DoT обгортає звичайний DNS у TLS на окремому порту (853), DoH вкладає його в HTTPS на порту 443, де він маскується під звичайний веб-трафік. Обидва ховають запити від тих, хто бачить канал, але резолвер бачить усе, а ділянка резолвер → авторитетні сервери лишається відкритою. Тому вибір резолвера — це вибір того, кому ви довіряєте свою історію імен. (Про TLS — модуль 15.)

Ще одну сучасну практику видно прямо в нашому захопленні нижче: мінімізацію імені запиту (QNAME minimization). Резолвер не розкриває корінню повне ім’я www.example.com, а питає лише про те, що цьому серверові потрібно знати: у корінь іде питання про com, а не про весь хост.

Лабораторний стенд для цього розділу — три авторитетні сервери BIND у просторі імен srv (корінь 10.0.0.11, зона test на 10.0.0.12, зона example.test на 10.0.0.13) і рекурсивний резолвер Unbound у просторі імен cli. Власний корінь дозволяє повторити все без інтернету; у лабораторній B5 ви збудуєте схожий.

Terminal window
dig web.example.test # A за замовчуванням, резолвер із resolv.conf
dig @10.0.0.13 web.example.test # спитати конкретний сервер
dig web.example.test +short # лише дані
dig example.test MX # тип запису
dig -x 192.0.2.10 # зворотне розв'язання (PTR)
dig +tcp web.example.test # примусово TCP
dig +norecurse @10.0.0.13 example.test NS # не просити рекурсію

У виводі читайте заголовок (status, прапорці), секцію відповіді (число ANSWER у заголовку) і Query time із SERVER внизу: чия саме це відповідь.

+trace не питає резолвер: dig сам повторює роботу рекурсивного резолвера, крок за кроком, і друкує кожну ланку делегування. Це найкращий спосіб довідатися, на якому рівні зламалося: корінь не знає TLD, TLD вказує на мертвий сервер, авторитетний відповідає інакше, ніж очікувалося.

Terminal window
dig +trace +nodnssec @10.0.0.11 www.example.test A
. 86400 IN NS a.root.test.
;; Received 96 bytes from 10.0.0.11#53(10.0.0.11) in 0 ms
test. 86400 IN NS ns.test.
;; Received 110 bytes from 10.0.0.11#53(a.root.test) in 0 ms
example.test. 86400 IN NS ns1.example.test.
;; Received 107 bytes from 10.0.0.12#53(ns.test) in 4 ms
www.example.test. 300 IN CNAME web.example.test.
web.example.test. 300 IN A 192.0.2.10
web.example.test. 300 IN A 192.0.2.11
example.test. 300 IN NS ns1.example.test.
;; Received 157 bytes from 10.0.0.13#53(ns1.example.test) in 0 ms

Три переходи: корінь відсилає до test, сервер test до example.test, і лише останній дає відповідь. Зверніть увагу, що в рядку Received завжди вказано, хто щойно відповів. На справжньому інтернеті вивід довший: першим іде перелік усіх тринадцяти кореневих серверів, а при DNSSEC (без +nodnssec) додаються рядки RRSIG і DS.

Що відбувається по мережі

Section titled “Що відбувається по мережі”

У просторі імен srv слухаємо порт 53, а з cli питаємо резолвер із порожнім кешем про web.example.test, двічі:

Terminal window
ip netns exec srv tcpdump -nn -i v1 'port 53'
10.0.0.2.48359 > 10.0.0.11.53: 33248% [1au] NS? . (28)
10.0.0.11.53 > 10.0.0.2.48359: 33248*- 1/0/2 NS a.root.test. (68)
10.0.0.2.45316 > 10.0.0.11.53: 57965% [1au] A? test. (33)
10.0.0.11.53 > 10.0.0.2.45316: 57965- 0/1/2 (66)
10.0.0.2.12915 > 10.0.0.12.53: 62830% [1au] A? example.test. (41)
10.0.0.12.53 > 10.0.0.2.12915: 62830- 0/1/2 (75)
10.0.0.2.57650 > 10.0.0.13.53: 41709% [1au] A? web.example.test. (45)
10.0.0.13.53 > 10.0.0.2.57650: 41709*- 2/1/2 A 192.0.2.11, A 192.0.2.10 (111)

Вісім пакетів, чотири запити й чотири відповіді: та сама діаграма, що на рисунку. Кожен запит іде з нового випадкового порту, а не з порту 53: у поєднанні з випадковим 16-бітним ідентифікатором це ускладнює підробку відповіді. І питання до кореня й TLD стосуються лише test. та example.test., тобто видно мінімізацію імені. Другий такий самий запит до резолвера не створив жодного пакета: усе з кешу.

Діагностика в п’ять кроків

Section titled “Діагностика в п’ять кроків”
  1. getent hosts імʼя: що бачить програма. Порожньо, а dig знаходить? Дивіться /etc/hosts, nsswitch.conf, search.
  2. dig імʼя: що каже резолвер із resolv.conf. Перевірте status, ra, TTL.
  3. dig @8.8.8.8 імʼя чи інший публічний резолвер: чи збігається з вашим. Різні відповіді означають різні кеші чи підміну на шляху.
  4. dig +trace імʼя: що кажуть самі авторитетні сервери. Тут видно делегування, мертвий NS, розбіжність між серверами зони.
  5. dig @<авторитетний> імʼя для кожного NS: однакова відповідь? Якщо серійні номери SOA різні, вторинний сервер відстав від первинного.

За жартом стоять цілком реальні механізми, і всі вони вже траплялися в цьому модулі:

  • Кеші з TTL: зміна не діє всюди одразу, а виправлена помилка ховається за негативним кешем.
  • Кілька шарів кешу, і кожен із власним віком, тому різні користувачі бачать різне.
  • Резолвер із першого рядка resolv.conf не відповідає, і кожен запит чекає таймаут. Програма «зависає» на секунди, а то й десятки секунд, без жодного повідомлення.
  • search і ndots перетворюють одне ім’я на кілька запитів.
  • Обрізані відповіді й заблокований TCP 53 ламають лише великі відповіді.
  • AAAA є, а IPv6 не працює: клієнт чекає на адресу, що ніколи не відповість (про це модуль 10).
  • Різні відповіді зсередини й ззовні (split-horizon), заплановані, але забуті.
  • Розходження між NS: один із серверів зони віддає застарілі дані, а запити розподіляються між ними довільно, і помилка стає «плаваючою».

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

Типові помилки розуміння

Section titled “Типові помилки розуміння”

«Зміна запису розійдеться по світу за кілька годин (propagation)». Ніякого розсилання нема. Резолвери самі питають і кешують на TTL. Нове значення «з’являється» у кожного резолвера в момент, коли в нього протухає старе, тобто не пізніше ніж за TTL після зміни (плюс негативний кеш, якщо запису раніше не було).

«dig показує те, що бачить моя програма». dig питає DNS напряму й не читає /etc/hosts та nsswitch.conf. Те, що бачить програма, покаже getent hosts.

«DNS працює по UDP». Здебільшого так, але не лише: обрізані відповіді (а з DNSSEC вони трапляються частіше) і перенесення зон ідуть за TCP, а DoT і DoH працюють поверх TLS. Мережа, що блокує TCP 53, ламає DNS частково.

«DNSSEC шифрує DNS». Він лише підписує: підробку видно, але запити ніхто не ховає. Таємність дають DoT і DoH, а вони не підтверджують правдивості відповіді.

«CNAME — це перенаправлення на інший сайт». Це псевдонім імені в DNS: клієнт усе одно підключається за адресою цільового імені й відправляє початкове ім’я у своєму HTTP-запиті. Жодних перенаправлень на рівні HTTP тут нема.

«Кореневих серверів тринадцять». Тринадцять імен, за якими стоять сотні екземплярів на всіх континентах. Адреси однакові, а маршрутизація доставляє до найближчого (anycast).

Перевір себе

1. Ви змінили A-запис із TTL 3600 і одразу перевіряєте з телефона через мобільного провайдера: там старе значення. Чому так і коли зміниться?
2. ping example.internal працює, а dig example.internal повертає порожньо. Яке пояснення найімовірніше?
3. Чим відрізняються NXDOMAIN і NODATA?
4. Сайт відкривається на всіх машинах, окрім однієї, де `dig @8.8.8.8` дає правильну адресу, а `dig` без сервера — стару. Куди дивитись?
5. Навіщо в записі NS у батьківській зоні іноді стоїть ще й адреса (glue)?
6. Що гарантує DNSSEC?
7. Невеликі запити працюють, а деякі доменні імена з великими відповідями (багато TXT) іноді не розв’язуються. Що перевірити першим?
  • A5. Ітеративний DNS-резолвер: розбір формату повідомлення, хід від кореня вниз по делегуваннях, кеш із TTL: усе, що ви бачили в dig +trace і в захопленні.
  • B5. Власні DNS і TLS: авторитетна зона, рекурсивний резолвер і перевірка dig +trace у власній ієрархії.
  • Kurose, Ross, Computer Networking: A Top-Down Approach, розділ про DNS
  • Peterson, Davie, Computer Networks: A Systems Approach, розділ про іменування
  • Liu, Albitz, DNS and BIND (O’Reilly)
  • RFC 1034 і RFC 1035: основа DNS; RFC 2308 (негативне кешування)
  • RFC 4033, 4034, 4035 (DNSSEC); RFC 7858 (DoT); RFC 8484 (DoH)
  • man 1 dig, man 5 resolv.conf, man 5 nsswitch.conf, man 1 getent, man 1 resolvectl
  • Документація Unbound і BIND 9