Этап 2 — DNS: полный путь резолвинга

«Это всегда DNS» — народная мудрость SRE. Этот этап — детальный разбор того, что происходит между «браузер хочет открыть example.com» и «нашёл IP». Понимая каждый шаг, ты разруливаешь 90% инцидентов в продакшене.

Рабочая ситуация

«Инцидент: после переезда сервиса на новый IP половина клиентов ещё час ходила на старый — хотя A-запись поменяли мгновенно». Прежде чем читать: как бы ты объяснил это руководству и что сделал бы за сутки ДО переезда, чтобы такого не было? Ответ — в разделе про TTL.

Что узнаешь — после урока ты сможешь
Вспомни из прошлого урока

В этапе 1 браузер разобрал URL и не нашёл ответа в кэшах — значит, нужен IP хоста. Ты уже знаешь: hostname приведён к ASCII (punycode), запросом займётся network process, а dns-prefetch мог запустить резолвинг заранее. База уровня «что такое DNS вообще» — в «Сети с нуля», урок 5.

1. Полная цепочка резолвинга

Браузер не знает, как «найти» IP домена. Он передаёт эту задачу резолверу операционной системы — а уже тот лезет в сеть. Полный путь:

Резолвинг app.example.com — все шаги 💻 Браузер (кэш) 🖥️ ОС — stub resolver 📋 /etc/hosts 📡 Recursive resolver 🌍 Root servers (13) 📦 .com TLD servers 🎯 example.com NS 🎁 IP 93.184.216.34 1) есть в кэше? 2) ОС спрашивает 2.5) hosts? 3) к recursive 4) спроси у root 5) к TLD 6) к authoritative 7) ответ возвращается

Каждый из этих этапов может иметь кэш, может пойти по DoT/DoH, может вернуть ошибку, может быть отравлен — обо всём по порядку.

2. Stub resolver — то, что в твоей ОС

Stub resolver — это библиотека в ОС, к которой обращаются программы за резолвингом. Она не делает рекурсию сама — а отправляет один UDP-пакет к рекурсивному резолверу (DNS-серверу, прописанному в настройках сети).

Linux — кто резолвит на самом деле

Тут запутанная история. В современных дистрибутивах:

  1. glibc (или musl) предоставляет API getaddrinfo()
  2. Оно смотрит в /etc/nsswitch.conf — порядок источников. Обычно: files dns = сначала /etc/hosts, потом DNS.
  3. Файл /etc/resolv.conf говорит, к какому DNS-серверу идти.
  4. Но в большинстве систем resolv.conf — это симлинк на /run/systemd/resolve/resolv.conf, который автогенерируется systemd-resolved.
  5. systemd-resolved слушает на 127.0.0.53:53 и сам делает запросы наружу — с кэшем, с DNSSEC, с DoT.
# Что у тебя реально настроено
cat /etc/resolv.conf
# nameserver 127.0.0.53
# options edns0 trust-ad
# search lan

# Реальные серверы, к которым идёт systemd-resolved
resolvectl status

# Кэш systemd-resolved
resolvectl statistics

# Очистить кэш
sudo resolvectl flush-caches

macOS

Использует mDNSResponder. Резолвер настраивается в System Settings → Network. Очистка кэша:

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

Windows

ipconfig /displaydns       # текущий кэш
ipconfig /flushdns         # очистить

3. /etc/hosts — самый простой override

До любого DNS-запроса ОС смотрит в /etc/hosts (на Windows — C:\Windows\System32\drivers\etc\hosts). Формат прост:

127.0.0.1   localhost
::1         localhost
192.168.1.50 dev.example.com
93.184.216.34 example.com

Это удобно для:

Помни: hosts поддерживает только статическое соответствие. Никаких wild-cards, никаких CNAME — только IP ↔ имя.

4. Recursive resolver — кто делает всю работу

Stub отправил запрос на адрес рекурсивного резолвера (например 1.1.1.1 Cloudflare или 8.8.8.8 Google). Резолвер должен дать ответ — даже если для этого ему нужно опросить десяток серверов.

Аналогия

DNS — это справочное бюро с ленивым клиентом

Stub resolver — ты сам: звонишь в справочную и ждёшь готовый ответ, никуда не бегая. Рекурсивный резолвер — оператор справочной: если ответа нет в его картотеке (кэше), он обзванивает инстанции по цепочке: центральный архив (root) говорит, в каком ведомстве искать (.com TLD), ведомство — в каком отделе (авторитетный сервер домена), и только отдел знает сам ответ. Оператор записывает ответ в картотеку с пометкой «действителен N минут» (TTL) — следующему звонящему ответит мгновенно и не будет никого обзванивать.

Что делает резолвер

  1. Смотрит в свой кэш. Если есть запись и TTL не истёк — отвечает сразу. 95% запросов решаются здесь.
  2. Если нет — итеративный обход. Идёт к root, потом к TLD, потом к authoritative.
  3. Возвращает ответ stub-у. И кэширует у себя на TTL.

Резолвер также может выполнять negative caching — запомнить «такого имени НЕТ» (ответ NXDOMAIN). Это тоже кэшируется, но обычно на меньший TTL.

5. Итеративные запросы вверх по дереву

Допустим, кэш резолвера пуст. Тогда:

# 1. Идёт к одному из 13 root-серверов (адреса root знает каждый резолвер)
# Спрашивает: «кто отвечает за .com?»
$ dig @a.root-servers.net app.example.com

# Ответ: «не я, иди к этим NS-серверам:
#   .com → a.gtld-servers.net, ..., m.gtld-servers.net»

# 2. Идёт к одному из .com-серверов
# «Кто отвечает за example.com?»
$ dig @a.gtld-servers.net app.example.com

# Ответ: «не я, иди к ns1.example.com / ns2.example.com»

# 3. Идёт к authoritative-серверу example.com
# «Какой A у app.example.com?»
$ dig @ns1.example.com app.example.com

# Ответ: «A 93.184.216.34, TTL 300»

Это 3 round-trip минимум. Каждый ~30-100мс. Итого 100-300мс на «холодный» резолвинг. Поэтому резолверы агрессивно кэшируют — следующий запрос вернётся за <5 мс.

Glue records — почему не петля

Постой. Authoritative-сервер для example.com — это ns1.example.com. Но чтобы узнать IP ns1.example.com, надо… резолвить example.com. Курица и яйцо.

Решение — glue records: в ответе TLD-сервера приклеивается не только имя, но и IP NS-сервера:

;; AUTHORITY SECTION:
example.com.    172800  IN  NS  ns1.example.com.
example.com.    172800  IN  NS  ns2.example.com.

;; ADDITIONAL SECTION (glue):
ns1.example.com. 172800 IN  A   192.168.0.10
ns2.example.com. 172800 IN  A   192.168.0.11

Иначе резолвер бы зациклился.

6. Типы записей и Resource Records

Запись в DNS — это Resource Record (RR). У неё фиксированный формат:

example.com.    300    IN    A    93.184.216.34
[name]         [TTL]  [class] [type]   [data]

Класс почти всегда IN (Internet) — остальные исторические. Типы — много, но реально важных пара десятков:

ТипЧто означаетПример data
AIPv4-адрес93.184.216.34
AAAAIPv6-адрес2606:2800:220:1:248:1893:25c8:1946
CNAMEАлиас на другое имяwww → example.com
NSAuthoritative-сервер зоныns1.example.com
SOA«Метаданные» зоныns1.x. admin.x. 2026010101 7200 3600 …
MXКуда доставлять почту10 mail.example.com
TXTПроизвольный текст"v=spf1 include:..."
CAAКакому CA можно выпускать сертификат0 issue "letsencrypt.org"
SRVСервис+порт+приоритет_sip._tcp 10 5 5060 sip.x
PTRОбратный резолвинг IP → имяв зоне in-addr.arpa
HTTPS / SVCBНовые: хинты для подключения (ALPN, port, ECH)1 . alpn="h3,h2"
DS / DNSKEY / RRSIGDNSSECкриптографические данные

7. CNAME — тонкости и подводные камни

CNAME — это «псевдоним». Когда резолвер видит www.example.com → CNAME example.com, он автоматически идёт резолвить example.com и возвращает уже его A-запись.

Правило: CNAME должен быть один

Рядом с CNAME не может быть других записей того же имени. Это правило часто нарушают — и DNS-софт ругается «CNAME and other data».

Apex-домен не может быть CNAME

Корень зоны (example.com без префикса) уже имеет SOA и NS — поэтому туда нельзя CNAME. Это техническое ограничение DNS.

Как обойти? Облачные DNS придумали псевдо-CNAME для apex:

Цепочки CNAME

CNAME может указывать на CNAME, который указывает на CNAME. Резолвер пройдёт все звенья. Но каждое звено = +RTT, и большинство клиентов не пройдут больше 8 звеньев.

CNAME-цепочка с CloudFront

Типичный путь:

www.example.com    CNAME  app.example.com
app.example.com    CNAME  d1234abc.cloudfront.net
d1234abc.cloudfront.net  CNAME  loadbalancer-eu.cloudfront.net
loadbalancer-eu.cloudfront.net  A  13.224.55.10

Браузер делает один запрос — но резолвер идёт по 4 шагам. В реальности CDN отдаёт несколько A-записей сразу (с anycast / Geo), и резолвер кэширует всё в одном ответе.

8. TTL — кэш и инвалидация

Каждая запись имеет TTL в секундах. Что значит «эта запись действительна столько-то».

TTL — это верхняя граница кэша. Реально:

Это значит — низкий TTL не гарантирует мгновенного переключения, но позволяет, например, через 5 минут быть уверенным, что 95% клиентов уже на новом адресе.

Стратегия миграции

  1. Сутки до миграции: уменьшаешь TTL с 3600 до 60
  2. Ждёшь сутки — за это время по всему миру старый TTL «сожрётся»
  3. Час X: меняешь A-запись на новый IP
  4. Через 1-5 минут 95% клиентов уже идут на новый сервер
  5. Через 30 минут старый сервер можно отключать
  6. На следующий день — возвращаешь TTL обратно к 3600

Negative caching

Когда резолвер получает «NXDOMAIN» (нет такой записи), он тоже это кэширует — но с другим TTL (берётся из SOA). Это значит, что если ты создаёшь новый поддомен new.example.com, а кто-то его уже спрашивал до создания и получил NXDOMAIN — он будет видеть «нет такого» ещё какое-то время.

9. DNS over TLS и DNS over HTTPS

Обычный DNS — UDP, нешифрованный. Это значит:

Чтобы это решить, придумали:

DoT — DNS over TLS

Стандартный TLS, порт 853. Провайдер видит, что ты общаешься с 1.1.1.1, но не видит содержимого запросов.

DoH — DNS over HTTPS

HTTPS, порт 443. Снаружи неотличимо от обычного веб-трафика — нельзя даже понять, что это DNS. Используется в Chrome/Firefox.

# Проверить DoH
curl -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=example.com&type=A'

# Проверить DoT
kdig -d @1.1.1.1 +tls example.com

В Chrome → Settings → Privacy → Security → «Use secure DNS» — там переключается.

Это только вход в тему

Здесь названы два транспорта из четырёх и не разобрано главное для инженера: что именно каждый из них скрывает, а что оставляет на виду, и почему шифрование запроса не прячет сам факт обращения к сайту. Полный разбор — в уроке шифрованный DNS: DoT, DoH, DoQ, ODoH и ECH. Там же — почему переход на шифрованный резолвер ломает корпоративную фильтрацию и что с этим делают на практике.

10. DNSSEC — криптографическая подпись зоны

DoT/DoH защищают канал. Но что, если злоумышленник взломал сам резолвер или authoritative-сервер? DNSSEC подписывает DNS-записи цифровой подписью.

Как работает (упрощённо):

Резолвер может проверить любую запись: подпись настоящая? родительская зона признаёт этот ключ? — и так до корня.

⚠️ DNSSEC и сломанные зоны

Большинство сайтов в интернете DNSSEC не используют. Из тех, что используют, многие иногда «ломаются» — забыли обновить подпись, ключ просрочился. Если резолвер строго проверяет DNSSEC — такая зона становится «недоступной». Поэтому многие резолверы по умолчанию не валидируют DNSSEC.

11. ECS — EDNS Client Subnet

Когда ты идёшь к 8.8.8.8, authoritative-сервер видит, что запрос пришёл с IP Google (а не с твоего). Если authoritative — это CDN (Cloudflare, Akamai), он хочет вернуть IP ближайшего edge к тебе, а не к Google.

Решение — EDNS Client Subnet (ECS): резолвер добавляет в запрос «оригинальный клиент пришёл из подсети 85.142.55.0/24». Authoritative использует это для GeoDNS-логики.

Минус — потеря приватности (твоя подсеть теперь видна authoritative). Cloudflare 1.1.1.1 принципиально не отправляет ECS — поэтому иногда даёт чуть медленный edge.

12. HTTPS / SVCB — новые записи 2023+

Относительно новый тип записи, поддерживается Chrome/Firefox/Safari. Решает несколько проблем сразу:

example.com.   3600  IN  HTTPS  1 . alpn="h3,h2" port=443 ipv4hint="1.2.3.4" ipv6hint="2001:db8::1" ech="..."

В одной записи:

Это позволяет браузеру начать соединение быстрее и приватнее. Cloudflare уже использует.

13. Что идёт не так в DNS и как дебажить

СимптомВозможная причинаКоманда
«Не открывается у меня, у других ок»Локальный кэш OS / браузераflushdns / resolvectl flush-caches
«У всех у одного провайдера лежит»Их рекурсивный резолвер сломанdig @1.1.1.1 my.com — работает? значит твой резолвер виноват
«После миграции половина на старом»TTL не вышел или резолверы игнорятПодождать или попросить очистить
«В Европе работает, в США нет»GeoDNS отдаёт разные IP, один из них лежитdig @8.8.8.8 vs dig @1.1.1.1 — сравнить
«Получаю NXDOMAIN, хотя запись есть»Negative cache, неправильные NSdig +trace — какой шаг сломан?
«SERVFAIL»Authoritative-сервер недоступен / DNSSEC сломанdig +cd — отключить DNSSEC проверку

14. Мини-лаба: попробуй прямо сейчас

Нужен только терминал (в Windows — WSL или онлайн-терминал; dig есть в пакете bind-utils/dnsutils). Прогони команды на любом домене и найди в выводе то, о чём был урок:

# Самая полезная команда — полный трейс
dig +trace app.example.com
# Покажет каждый шаг: root → .com → ns1.example.com → ответ
# Видно, кто и что сказал на каждом уровне

# Конкретный резолвер
dig @1.1.1.1 example.com
dig @8.8.8.8 example.com
dig @9.9.9.9 example.com           # Quad9 — блокирует malware

# Конкретный тип
dig example.com MX
dig example.com TXT
dig example.com NS
dig example.com CAA
dig example.com HTTPS

# Обратный резолвинг
dig -x 8.8.8.8                     # 8.8.8.8 → dns.google

# С DNSSEC флагами
dig +dnssec example.com
dig +cd example.com                # отключить проверку (для дебага)

# Через DoH
dig @1.1.1.1 +https example.com
kdig @1.1.1.1 +https example.com
curl -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=example.com&type=A'
Ожидаемый результат

В dig +trace ты увидишь три «этажа» из схемы раздела 1: список root-серверов, затем NS-серверы TLD, затем авторитетные NS домена и финальную A-запись. Обрати внимание на TTL в каждом ответе и на ADDITIONAL SECTION у TLD — это те самые glue-записи. Второй запуск dig example.com (без @) вернёт ответ с уменьшившимся TTL — значит, ты читаешь его из кэша своего резолвера, а не с авторитетного сервера.

15. Что с этим делает DevOps

16. Задачи самопроверки — реши, потом раскрой ответ

Задача 1. Ты создал поддомен api.example.com 10 минут назад, но у коллеги он «не существует» (NXDOMAIN), хотя dig @ns1.example.com api.example.com отвечает правильно. Что случилось и что делать?

Коллега (или его резолвер) спрашивал имя ДО создания записи и получил NXDOMAIN — тот закэшировался (negative caching, TTL из SOA). Авторитетный сервер уже отвечает верно — значит, зона в порядке, надо лишь дождаться истечения негативного кэша или сбросить кэш резолвера/ОС (resolvectl flush-caches, ipconfig /flushdns). Вывод на будущее: перед анонсом новых имён не «прощупывать» их заранее.

Задача 2. Нужно, чтобы корень домена example.com вёл на CDN, который даёт только имя d1234.cdn-provider.net. CNAME на apex поставить нельзя. Твои варианты?

Классическое ограничение: на apex уже есть SOA/NS, CNAME рядом запрещён. Варианты: ALIAS-запись (Route 53) или CNAME flattening (Cloudflare) — DNS-провайдер сам резолвит имя CDN и отдаёт клиентам готовые A/AAAA; либо перенести сайт на www (а с apex сделать редирект); либо использовать провайдера, поддерживающего HTTPS/SVCB-записи.

Задача 3. Через час — переключение базы на новый адрес, у записи db.example.com TTL 3600. Успеешь ли переключить трафик «мгновенно» в час X? Как надо было готовиться?

Не успеешь: резолверы по всему миру имеют право держать старый ответ до часа после последнего запроса. Правильно: за сутки до миграции снизить TTL до 60, дождаться, пока старый TTL везде истечёт, в час X поменять запись — через 1–5 минут почти все клиенты на новом адресе. После миграции вернуть TTL обратно, чтобы не грузить резолвинг.

Задача 4. Пользователи одного провайдера жалуются «сайт не открывается», у остальных всё работает. Какие две команды быстро локализуют проблему?

dig my-site.com (через резолвер провайдера) и dig @1.1.1.1 my-site.com (через публичный). Если через 1.1.1.1 имя резолвится, а через провайдерский резолвер — нет, проблема в его рекурсивном резолвере (кэш, фильтрация, поломка), и это аргумент для обращения к провайдеру; сайт и зона в порядке.

Задача 5. После включения DNSSEC на домене часть пользователей стала получать SERVFAIL. dig +cd your.com при этом отвечает нормально. Что это значит?

+cd (checking disabled) отключает валидацию DNSSEC — раз с ним ответ приходит, а без него SERVFAIL, значит валидирующие резолверы бракуют подпись зоны: просроченный RRSIG, несовпадающий DS у регистратора или потерянный DNSKEY. Чинится на стороне зоны: перевыпуск подписей и сверка DS-записи у родителя.

17. Словарик урока

заглушка-резолвер · stub resolverбиблиотека ОС: передаёт запрос рекурсивному резолверу и ждёт готовый ответ
рекурсивный резолвер · recursive resolverсервер, который сам обходит дерево DNS и кэширует ответы
авторитетный сервер · authoritative serverсервер, который хранит зону и даёт финальный ответ за свой домен
ресурсная запись · resource record (RR)единица данных DNS: имя, TTL, класс, тип, значение
склейка · glue recordIP NS-сервера в ответе родительской зоны — разрывает «курицу и яйцо»
время жизни · TTLсколько секунд ответ можно держать в кэше; главный рычаг миграций
негативный кэш · negative cachingкэширование ответа «имени нет» (NXDOMAIN) с TTL из SOA
DoT / DoHDNS поверх TLS (порт 853) / поверх HTTPS (443): шифруют канал до резолвера
DNSSECцифровые подписи записей (RRSIG/DNSKEY/DS): защищают содержимое, а не канал
клиентская подсеть · EDNS Client Subnetрезолвер сообщает авторитетному подсеть клиента для GeoDNS
split-horizonразные ответы на одно имя изнутри и снаружи сети (внутренний/внешний вид зоны)

Чек-лист «понимаю это»

DNS — это распределённая иерархическая база с агрессивным кэшированием на каждом уровне. Цепочка: браузер кэш → ОС stub → /etc/hosts → recursive resolver → root → TLD → authoritative. TTL — главный рычаг. DoT/DoH защищают канал, DNSSEC — содержимое. Новые записи HTTPS/SVCB ускоряют установление соединения.
Мост к следующему уроку

DNS вернул IP. Но стоп: для крупного сайта он вернул какой-то из десятков адресов — и почему-то тот, до которого тебе 10 мс, а не 200. Кто решил, что тебе ближе Франкфурт, а не Сингапур, и как один IP-адрес умудряется «жить» сразу на всех континентах? Это следующий этап — CDN, Anycast и edge routing.