Этап 2 — DNS: полный путь резолвинга
«Это всегда DNS» — народная мудрость SRE. Этот этап — детальный разбор того, что происходит между «браузер хочет открыть example.com» и «нашёл IP». Понимая каждый шаг, ты разруливаешь 90% инцидентов в продакшене.
«Инцидент: после переезда сервиса на новый IP половина клиентов ещё час ходила на старый — хотя A-запись поменяли мгновенно». Прежде чем читать: как бы ты объяснил это руководству и что сделал бы за сутки ДО переезда, чтобы такого не было? Ответ — в разделе про TTL.
- Проследить запрос имени через все руки: браузер → stub → /etc/hosts → рекурсивный → root → TLD → авторитетный
- Прочитать вывод
dig +traceи показать, на каком шаге резолвинг сломан - Спланировать DNS-миграцию через снижение TTL — без часового «хвоста» старых клиентов
- Выбрать тип записи под задачу (A/AAAA, CNAME и его запреты, MX, TXT, CAA, HTTPS/SVCB)
- Объяснить, что защищает DoT/DoH, а что — DNSSEC, и почему это разные угрозы
- Диагностировать классику: NXDOMAIN из негативного кэша, SERVFAIL из-за DNSSEC, GeoDNS-расхождения
В этапе 1 браузер разобрал URL и не нашёл ответа в кэшах —
значит, нужен IP хоста. Ты уже знаешь: hostname приведён к ASCII (punycode), запросом займётся
network process, а dns-prefetch мог запустить резолвинг заранее. База уровня «что
такое DNS вообще» — в «Сети с нуля», урок 5.
1. Полная цепочка резолвинга
Браузер не знает, как «найти» IP домена. Он передаёт эту задачу резолверу операционной системы — а уже тот лезет в сеть. Полный путь:
Каждый из этих этапов может иметь кэш, может пойти по DoT/DoH, может вернуть ошибку, может быть отравлен — обо всём по порядку.
2. Stub resolver — то, что в твоей ОС
Stub resolver — это библиотека в ОС, к которой обращаются программы за резолвингом. Она не делает рекурсию сама — а отправляет один UDP-пакет к рекурсивному резолверу (DNS-серверу, прописанному в настройках сети).
Linux — кто резолвит на самом деле
Тут запутанная история. В современных дистрибутивах:
- glibc (или musl) предоставляет API
getaddrinfo() - Оно смотрит в
/etc/nsswitch.conf— порядок источников. Обычно:files dns= сначала/etc/hosts, потом DNS. - Файл
/etc/resolv.confговорит, к какому DNS-серверу идти. - Но в большинстве систем
resolv.conf— это симлинк на/run/systemd/resolve/resolv.conf, который автогенерируетсяsystemd-resolved. 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
Это удобно для:
- Тестов («хочу проверить, как поведёт себя сайт на этом IP до DNS-миграции»)
- Локальной разработки (
dev.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) — следующему звонящему ответит мгновенно и не будет никого обзванивать.
Что делает резолвер
- Смотрит в свой кэш. Если есть запись и TTL не истёк — отвечает сразу. 95% запросов решаются здесь.
- Если нет — итеративный обход. Идёт к root, потом к TLD, потом к authoritative.
- Возвращает ответ 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 |
|---|---|---|
| A | IPv4-адрес | 93.184.216.34 |
| AAAA | IPv6-адрес | 2606:2800:220:1:248:1893:25c8:1946 |
| CNAME | Алиас на другое имя | www → example.com |
| NS | Authoritative-сервер зоны | 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 / RRSIG | DNSSEC | криптографические данные |
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:
- Route 53 ALIAS — внутри AWS делает «вид» что есть CNAME на apex, но при ответе резолверу возвращает A-записи целевого сервиса
- Cloudflare CNAME Flattening — то же самое
Цепочки 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 до десятков минут
- Браузеры обычно кэшируют 30-60 секунд независимо от TTL
- Большие облачные резолверы (1.1.1.1, 8.8.8.8) могут кэшировать минимум 30-60 сек, даже если TTL=10
Это значит — низкий TTL не гарантирует мгновенного переключения, но позволяет, например, через 5 минут быть уверенным, что 95% клиентов уже на новом адресе.
Стратегия миграции
- Сутки до миграции: уменьшаешь TTL с 3600 до 60
- Ждёшь сутки — за это время по всему миру старый TTL «сожрётся»
- Час X: меняешь A-запись на новый IP
- Через 1-5 минут 95% клиентов уже идут на новый сервер
- Через 30 минут старый сервер можно отключать
- На следующий день — возвращаешь TTL обратно к 3600
Negative caching
Когда резолвер получает «NXDOMAIN» (нет такой записи), он тоже это кэширует — но с другим TTL (берётся из SOA). Это значит, что если ты создаёшь новый поддомен new.example.com, а кто-то его уже спрашивал до создания и получил NXDOMAIN — он будет видеть «нет такого» ещё какое-то время.
9. DNS over TLS и DNS over HTTPS
Обычный DNS — UDP, нешифрованный. Это значит:
- Провайдер видит все твои запросы
- Провайдер может их подменить (например, перенаправить тебя на свой портал)
- Простые MITM-атаки в публичном Wi-Fi
Чтобы это решить, придумали:
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-записи цифровой подписью.
Как работает (упрощённо):
- Каждая зона имеет ключи (KSK, ZSK). Открытый — в записи DNSKEY, приватный — у владельца зоны
- Все записи подписаны — RRSIG
- Родительская зона держит хэш ключа дочерней — DS
- Цепочка идёт до корня — он подписан особыми ключами (RFC 5011 Key Signing Ceremony — IRL ритуал ICANN)
Резолвер может проверить любую запись: подпись настоящая? родительская зона признаёт этот ключ? — и так до корня.
Большинство сайтов в интернете 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="..."
В одной записи:
- Какой ALPN поддерживается (HTTP/3, HTTP/2)
- Какой порт
- IPv4 и IPv6 хинты (можно установить соединение, не делая отдельных A/AAAA запросов)
- ECH (Encrypted Client Hello) — публичный ключ, которым клиент зашифрует SNI
Это позволяет браузеру начать соединение быстрее и приватнее. 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, неправильные NS | dig +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
- Управление DNS-зоной. Терраформ для Route 53 / Cloudflare. Все записи — в коде, ревью, history. Никаких ручных правок.
- Health-checked routing. Route 53 / Cloudflare Load Balancer умеет вместо одного A-ответа возвращать «здоровый» — это автоматический failover.
- Weighted routing. Подавать 90% трафика на v1, 10% на v2 — для canary deployments.
- SPF / DKIM / DMARC. Полная цепочка защиты почты от подделок — это TXT-записи. Без них твой домен спуфят.
- CAA-записи. Чтобы атакующий не выпустил TLS-сертификат у Let's Encrypt от твоего имени — указываешь конкретный CA.
- K8s — CoreDNS. Внутри кластера сервисы находят друг друга через DNS. Это твой Dataplane.
- External DNS. Оператор, который автоматически создаёт DNS-записи в облаке для Ingress'ов K8s.
- Мониторинг резолверов. Алерты на «не резолвится» в pod-ах — частая причина инцидентов.
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 vs recursive vs authoritative
- ☐ Помню, что такое glue records
- ☐ Знаю, когда CNAME, а когда A; почему apex не может быть CNAME
- ☐ Понимаю TTL и стратегию миграции через снижение TTL
- ☐ Различаю negative cache (NXDOMAIN, SERVFAIL)
- ☐ Знаю DoT vs DoH
- ☐ Понимаю смысл DNSSEC, ECS, HTTPS-записи
- ☐ Использовал
dig +trace - ☐ Прочитал
resolvectl statusна своём ноутбуке
DNS вернул IP. Но стоп: для крупного сайта он вернул какой-то из десятков адресов — и почему-то тот, до которого тебе 10 мс, а не 200. Кто решил, что тебе ближе Франкфурт, а не Сингапур, и как один IP-адрес умудряется «жить» сразу на всех континентах? Это следующий этап — CDN, Anycast и edge routing.