DNS-иерархия — root, TLD, authoritative, recursive resolvers
Когда ты вводишь в браузере github.com, происходит маленькое чудо: твой компьютер где-то узнаёт, что этому имени соответствует IP-адрес 140.82.114.4, и идёт по нему. Этот процесс называется DNS resolution (резолв DNS), и его обеспечивает одна из самых старых и важных систем интернета — DNS (Domain Name System).
DNS — это распределённая иерархическая база данных. Никто не хранит «полную таблицу» соответствий имён и IP-адресов. Информация разбросана по миллионам серверов по всему миру. Запросы маршрутизируются между ними по строгой иерархии. И вся эта махина обслуживает триллионы запросов в день, обычно за десятки миллисекунд.
В этом уроке разберём, как устроена иерархия: что такое root-серверы, как работают TLD, кто такие authoritative и recursive resolvers, и почему вся система не падает каждый день несмотря на её размеры.
Зачем нужен DNS
В сети есть IP-адреса (например, 140.82.114.4) — это то, чем оперируют сетевые протоколы. Но человеку запомнить десятки IP — невозможно. Поэтому изначально, ещё в 70-х в ARPANET, использовался файл HOSTS.TXT, где каждый администратор сети поддерживал список имён и адресов. Этот файл распространялся между всеми хостами.
С ростом сети это стало проблемой:
- Coordination cost. Все администраторы должны соглашаться на изменения. Реальная коллаборация невозможна на масштабе.
- Update propagation. Файл обновляется раз в неделю — изменения медленные.
- Single point of failure. Хост, на котором лежит мастер-копия, — bottleneck.
- Name conflicts. Кто решает, что
mail— это твой сервер или мой?
В 1983 Пол Мокапетрис описал DNS — распределённую иерархическую систему, которая решает все эти проблемы. С тех пор она почти не менялась в архитектурном плане, только добавлялись расширения.
Иерархия — пирамида имён
DNS-имя — это последовательность меток (labels), разделённых точками. Например, www.github.com состоит из:
www— самая «глубокая» метка.github— субдомен.com— Top-Level Domain (TLD).- (после
comесть невидимая точка — это root.)
Полное «техническое» имя — www.github.com. (с точкой в конце), это FQDN (Fully Qualified Domain Name). Точка в конце — это root-зона. Обычно её опускают для удобства.
Ключевая идея: каждый уровень иерархии знает только следующий уровень. Root не знает www.github.com — он знает только, где живут TLD-серверы .com. TLD .com не знает www.github.com — он знает только NS-серверы для github.com. И только authoritative-серверы github.com знают конкретные записи.
Это даёт масштабируемость: ни один сервер не нагружается миллиардами имён. Распределение нагрузки между миллионами зон.
Root-серверы — основа всего
Root-серверы (root-servers.net) — это начало всех DNS-резолвов. Их 13 логически, обозначены буквами от a до m. Например:
a.root-servers.net— управляется Verisign.b.root-servers.net— USC ISI.c.root-servers.net— Cogent Communications.- …
m.root-servers.net— WIDE Project (Япония).
Почему «логически 13»? Физически каждый «root-server» — это anycast-кластер из сотен серверов по всему миру. Запрос к одному IP-адресу приходит на ближайший физически сервер (благодаря BGP anycast). Так что каждый из 13 root-операторов держит десятки или сотни физических серверов.
Что хранят root-серверы: только NS-записи всех TLD. Это маленькая база (~1500 TLD * несколько NS на каждый = ~10 000 записей). Поэтому root-серверы могут отвечать молниеносно.
# Посмотри root-серверы и попроси у одного из них помощь:
dig +short . NS
# Список: a.root-servers.net через m.root-servers.net
# Спроси у root, кто отвечает за .com:
dig @a.root-servers.net com NS +noall +answer +authority
# Получишь NS-записи .com (Verisign): a.gtld-servers.net и т.д.
# Заметь: root не знает www.github.com -- он знает только TLD
dig @a.root-servers.net www.github.com +noall +authority
# Получишь NS для .com (через делегирование), не сам ответ
Root-серверы — критическая инфраструктура. Их потеря не означала бы немедленный конец интернета (DNS-кэши на recursive resolvers держат данные часами/днями), но повлекла бы крах в течение суток. Поэтому root-операторы очень параноидально относятся к надёжности и распределённости.
DNS и service discovery внутри DockerTLD-серверы — генеральные регистраторы
Под root живут TLD-серверы. Они хранят NS-записи всех доменов в своём TLD. Категории TLD:
- Generic TLD (gTLD):
.com,.org,.net,.info,.biz, и сотни «new gTLD» (.app,.dev,.ai, etc.). - Country-code TLD (ccTLD):
.ru,.uk,.de,.cn,.jp, etc. - Sponsored TLD (sTLD):
.gov,.edu,.mil— особые правила регистрации. - Infrastructure TLD:
.arpa— для технических нужд (in-addr.arpaдля reverse DNS).
Управление:
.com,.net— Verisign..org— Public Interest Registry..ru— Координационный центр национального домена.- Каждый ccTLD — управляется в своей стране.
Когда ты регистрируешь домен example.com через регистратора (Namecheap, GoDaddy), регистратор обращается к registry (Verisign для .com) и добавляет NS-записи: «authoritative-серверы для example.com — ns1.namecheap.com и ns2.namecheap.com». После этого .com-серверы знают, куда направить запросы про example.com.
# Посмотри NS-серверы для github.com на TLD-уровне:
dig @a.gtld-servers.net github.com NS +noall +authority
# Ты увидишь NS-серверы GitHub: ns-421.awsdns-52.com, ns-1707.awsdns-21.co.uk, etc.
# А теперь спроси у одного из них напрямую:
dig @ns-421.awsdns-52.com www.github.com A +noall +answer
# Получишь A-запись -- реальный IP сервера
Authoritative servers — конечная истина
Authoritative DNS-серверы — это серверы, которые владеют конкретной зоной и хранят её настоящие записи. Если ты владелец example.com, ты настраиваешь свои NS-записи на свои authoritative-серверы (или серверы DNS-провайдера — AWS Route 53, Cloudflare, Google Cloud DNS).
Authoritative-сервер для зоны знает:
- A-записи (IPv4):
www.example.com -> 1.2.3.4. - AAAA-записи (IPv6).
- MX-записи (mail exchangers).
- TXT-записи (произвольные текстовые, для SPF, DKIM, верификации).
- CNAME-записи (псевдонимы).
- NS-записи (делегирование субдоменов).
- … и другие типы.
Когда recursive resolver приходит за ответом и получает «настоящий» ответ от authoritative-сервера, в DNS-ответе устанавливается флаг AA (Authoritative Answer).
# Получи ответ от authoritative-сервера и посмотри на флаги:
dig @ns-421.awsdns-52.com www.github.com A
# В выводе строка ';; flags: qr aa rd ra'
# 'aa' -- Authoritative Answer
# Это значит ответ пришёл из 'первоисточника'
# Сравни с ответом от кэша:
dig www.github.com A
# Здесь aa нет -- ответ из cache resolver'а
Один домен может иметь несколько authoritative-серверов (обычно 2-4 NS-записей) для надёжности и распределения нагрузки. Они синхронизируются через zone transfers (AXFR/IXFR).
Recursive resolver — то, что ты вызываешь
Когда твой компьютер делает DNS-запрос, он не идёт сразу в root -> TLD -> authoritative. Он идёт к recursive resolver — DNS-серверу, который делает всю работу за тебя.
Самые известные recursive resolvers:
8.8.8.8и8.8.4.4— Google Public DNS.1.1.1.1и1.0.0.1— Cloudflare DNS (с фокусом на privacy).9.9.9.9— Quad9 (с малware-фильтрацией).- DNS-серверы твоего провайдера (обычно прописаны через DHCP).
- DNS-серверы корпоративной сети (для внутренних имён).
Recursive resolver:
- Получает твой запрос.
- Смотрит в кэш — может, уже знает ответ.
- Если нет — рекурсивно ходит по иерархии: root -> TLD -> authoritative.
- Получает ответ, кэширует с TTL.
- Возвращает тебе.
Recursive resolver делает за тебя 90% работы. Без него ты бы сам должен был знать всю иерархию и проходить её.
Recursive vs iterative — разница важна
В DNS есть два режима запроса:
-
Recursive (RD=1, Recursion Desired): клиент просит resolver «сделай всю работу, верни мне готовый ответ». Так работает связь client -> recursive resolver.
-
Iterative: клиент сам ходит по иерархии, на каждом сервере спрашивая «куда дальше». Так recursive resolver ходит к authoritative-серверам (root, TLD, ans).
Когда 8.8.8.8 запрашивает у root «где www.github.com?», root не делает работу за него (root не делает recursion). Root отвечает «я не знаю, но вот NS-серверы для .com — спроси у них». Это iterative ответ.
Конечный пользователь обычно делает recursive запрос. Это удобнее: одна UDP-датаграмма, один ответ. Никакая клиентская программа не знает иерархии в деталях.
# Recursive запрос (RD=1 по дефолту):
dig www.github.com
# В выводе: ';; flags: qr rd ra'
# rd = Recursion Desired (мы попросили)
# ra = Recursion Available (сервер умеет)
# Iterative запрос (RD=0):
dig +norecurse www.github.com
# Если recursive resolver, может отказаться отвечать (REFUSED).
# Если authoritative -- ответит то, что знает в своих зонах
# Понаблюдаем за iterative resolution вручную:
dig +trace www.github.com
# Это последовательно покажет каждый шаг:
# (1) root отвечает кто .com
# (2) .com отвечает кто github.com
# (3) github.com authoritative отвечает A
Зачем такая сложность
Может показаться, что 4-уровневая иерархия (root -> TLD -> authoritative -> record) с двумя видами серверов (recursive и authoritative) — избыточно. Но это и есть гениальность дизайна:
- Distributed. Никто не хранит всю базу. Нагрузка распределена между миллионами серверов.
- Self-managing. Владелец
example.comсам управляет своими записями, не нужно соглашений с глобальным админом. - Scalable. Добавь новый TLD, новый домен — иерархия выдержит без изменений.
- Failure-isolated. Падение authoritative-сервера
example.comвлияет только на этот домен. Падение TLD .com влияет на.com(миллионы доменов), но всё ещё не на root и не на другие TLD. - Caching-friendly. Каждый уровень кэшируется на recursive resolver’ах с TTL. На каждый запрос не нужно ходить через всю иерархию.
DNS работает уже больше 40 лет с этой архитектурой. Это один из самых удачных дизайнов в истории интернета.
CoreDNS в Kubernetes: internal service discoveryПопробуй сам
# 1. Прогуляйся по DNS-иерархии вручную:
dig +trace www.github.com
# Видишь каждый шаг: root -> .com -> github.com authoritative -> answer
# 2. Спроси root-сервер напрямую:
dig @a.root-servers.net . NS
# Получишь список root-серверов
# 3. Спроси TLD-сервер напрямую:
dig @a.gtld-servers.net github.com NS
# Получишь NS-серверы github.com
# 4. Спроси authoritative напрямую:
dig @ns-421.awsdns-52.com www.github.com A
# Получишь A-запись, флаг 'aa' стоит
# 5. Сравни ответы от разных recursive resolvers:
dig @8.8.8.8 www.github.com +short
dig @1.1.1.1 www.github.com +short
# Иногда отличаются -- DNS-провайдеры могут отдавать разные IP для CDN
# 6. Посмотри свой текущий resolver:
cat /etc/resolv.conf
# (или на macOS:)
scutil --dns | head -20
# 7. Сравни время ответа cached vs first hit:
dig +stats www.example.com
dig +stats www.example.com # повторный запрос -- из cache, быстрее