diff --git a/tools/dns/index.md b/tools/dns/index.md new file mode 100644 index 0000000000..83787ed62b --- /dev/null +++ b/tools/dns/index.md @@ -0,0 +1,458 @@ +--- +title: "Domain Name System" +description: "Система доменных имён, помогающая обращаться к сайтам по имени" +authors: + - disinterpreter +keywords: + - dns + - прикладной уровень + - домен +related: + - tools/network + - tools/tcp-udp-protocols + - tools/network-models +tags: + - article +--- + +## Кратко + +**Domain Name System** или **DNS** — система, которая позволяет преобразовывать доменные имена в IP-адреса. + +Интернет работает через связь между IP-адресами, но запоминать числовые последовательности неудобно. Если мы введём в браузере доменное имя _example.com_, оно будет ссылаться на IP-адрес вида _2001:0DB8::1_ или _192.0.2.1_. + +## Историческая справка + +Ещё до создания Интернета существовала сеть ARPAnet, которая являлась огромным сообществом сетевых узлов (компьютеров) и всю информацию о преобразовании IP-адресов в понятные названия производили в одном файле `HOSTS.TXT`, который лежал на сервере Стэнфордского научно-исследовательского института. Пользователи вручную брали этот файл и устанавливали на свою операционную систему, для удобного доступа к ресурсам. Со временем это стало неудобно, количество ресурсов и пользователей только росло, поэтому появилась отдельная система, которая проводит всю эту работу автоматически. + +Первая версия документа, описывающая DNS появилась в конце 80х, тогда в Интернете не было крупных техногигантов с огромными датацентрами и полной отказоустойчивостью. Поэтому, техническая составляющая системы работы доменов очень интересна. + + +## Как работает + +Работает всё это достаточно просто, при обращении к ресурсу по домену, устройство забирает с DNS-сервера записи, которые сопоставляют домен с IP-адресом. В нашем случае для домена _example.com_ будет AAAA-запись с IPv6 адресом _2001:0DB8::1_ и A-запись _192.0.2.1_. +Для исключения множественных запросов, локальное устройство имеет свой кеш, который хранит информацию о только что полученных записях. +В современных ОС обычно указываются два DNS-сервера, основной и альтернативный, для поддержания функционирования DNS в случае отключения одного из них. +В случае запроса не существующего домена, DNS вернёт статус _NXDOMAIN_ + +[//]: <> (Тут нужно нарисовать картинку, с одной стороны компьютер с другой планета символизирующая интернет, и показать процесс получения) + +## Ресурсные записи + +Служебные записи, с помощью которых и происходят привязки домена. +Рассмотрим несколько из них: + +| Название | Назначение | +|---------|------------| +| A | адресная запись, которая производит связку домена и IPv4 адреса | +| AAAA | адресная запись, которая производит связку домена и IPv6 адреса | +| CNAME | используется для перенаправления на другой домен | +| MX | указывает на почтовый шлюз | +| NS | запись, хранящая адрес узла, который отвечает за этот домен | +| PTR | обратная запись | +| TXT | текстовая запись | + + +### NS + +_NS_ записи указывают на DNS-серверы, которые отвечают за этот домен, чаще всего на то место, откуда производится настройка ресурсных записей этого домена. Они указываются не в DNS-зоне домена, а у провайдера, отвечающего за домен, чаще всего он предоставляет интерфейс для управления. + +Эти записи необходимы, если вам нужно перенести управление доменом на другой DNS-хостинг. Исторически, сервисы, которые занимались продажей доменов не имели своих DNS-серверов, а только давали возможность указать NS записи до необходимого DNS сервера. + +Проверить NS записи можно двумя командами, `nslookup` и `dig`. + +Через `nslookup` + +
+ nslookup + +``` +user@server:~$ nslookup -type=NS example.com +Server: 1.1.1.1 +Address: 1.1.1.1#53 + +Non-authoritative answer: +example.com nameserver = hera.ns.cloudflare.com. +example.com nameserver = elliott.ns.cloudflare.com. + +Authoritative answers can be found from: +``` + +
+ +Или через `dig` + +
+ dig + +``` +user@server:~$ dig NS example.com + +; <<>> DiG 9.20.11-4-Debian <<>> NS example.com +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23514 +;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 1232 +;; QUESTION SECTION: +;example.com. IN NS + +;; ANSWER SECTION: +example.com. 81538 IN NS hera.ns.cloudflare.com. +example.com. 81538 IN NS elliott.ns.cloudflare.com. + +;; Query time: 51 msec +;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP) +;; WHEN: Thu Jan 29 16:48:37 MSK 2026 +;; MSG SIZE rcvd: 95 +``` + +
+ +### PTR + +_PTR_ запись нельзя встретить в DNS записях о вашем домене, данная запись обычно прикрепляется Интернет или хостинг провайдером на IP-адрес для создания обратного соответствия. +Например у нас есть IP-адрес _2001:0DB8::1_ с PTR записью на _example.com_ если мы сделаем DNS lookup, командой `nslookup 2001:0DB8::1`, мы получим ответ в виде домена _example.com_. + +Пример из реального Интернета: +``` +user@server:~$ nslookup 2a02:6b8::feed:0ff +f.f.0.0.d.e.e.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.6.0.2.0.a.2.ip6.arpa name = dns.yandex.ru. + +Authoritative answers can be found from: +``` +или +``` +user@server:~$ nslookup 77.88.8.1 +1.8.88.77.in-addr.arpa name = secondary.dns.yandex.ru. + +Authoritative answers can be found from: +``` + +## TTL +У ресурсных записей есть свой _TTL_(Time To Live), время, которое запись будет находиться в кеш серверах, чтобы, кеш сервер не ходил за обновлением информации о данной ресурсной записи. TTL измеряется в секундах и следует понимать, чем меньше TTL, тем чаще кеш-сервер будет обращаться за новыми данными. + +Пример: + +``` +user@server:~$ dig +noall +answer AAAA example.com +example.com. 158 IN AAAA 2a06:98c1:3122:8000::1 +example.com. 158 IN AAAA 2a06:98c1:3123:8000::1 +``` +В случае примера, TTL составляет 158 секунд. +Важно понимать, резолвер или форвардер нам возвращает **оставшееся** время TTL, поэтому если вы введёте команду ещё раз, TTL будет уже другой. + +Чтобы посмотреть TTL который задан для домена, необходимо сделать запрос на взятие записи с NS-сервера данного домена + +Пример: +``` +user@server:~$ dig +noall +answer @hera.ns.cloudflare.com example.com AAAA +example.com. 300 IN AAAA 2a06:98c1:3123:8000::1 +example.com. 300 IN AAAA 2a06:98c1:3122:8000::1 +``` +TTL данной записи – 300 секунд. + +## Punycode +_Punycode_ или пью́никод или пáникод - метод преобразования unicode символов в ASCII представление. Изначально DNS работает только с ASCII символами и добавление доменов на языках отличных от английского было проблемой. Punycode и занимается решением этой проблемы. + +Перейдём к примерам, доменное имя `пример.рф` может быть представлено как `xn--e1afmkfd.xn--p1ai`. При попытке вставить эту punycode ссылку в ваш браузер, он его поймёт и переведёт в понятный вид. И наоборот, при попытке ввести в поисковую строку домен с юникодом, браузер сконвертирует его в punycode автоматически. + +Такой компромисс даёт не переписывать устоявшиеся системы и серверы. + +Важно заметить, punycode хорошо работает с электронной почтой, адрес `иван@пример.рф` будет совершенно легитимным и обработается любым современным почтовым сервером. + +Полную информацию о том, как проходит конвертация, можно почитать в [RFC 3492](https://datatracker.ietf.org/doc/html/rfc3492) + +[Веб-сайт](https://www.punycoder.com/) где можно посмотреть как конвертируются символы. + + +## Транспорты +Основная проблема работы DNS по UDP это отсутствие шифрования, все DNS запросы видны участникам, которые обрабатывают ваш проходящий трафик, поэтому были изобретены разные способы это исправить. +Изначально, DNS работал на 53 порту протокола UDP, но на сегодняшний день существует несколько транспортных реализаций, таких как DNS over HTTPS, DNS over TLS и DNS over QUIC. В качестве примера рассмотрим первый вариант. + +### DNS over HTTPS +В данном случае в качестве шифрования и передачи используется протокол HTTPS, принцип определён в RFC 8484 и он достаточно прост. +На DNS сервере стоит HTTPS сервер, в нем находится GET или POST эндпоинт `/dns-query?dns=`, где в значении dns будет base64 DNS реквеста (не забываем, DNS это протокол, где данные передаются в байтах), как при передаче по UDP. В случае успеха, придёт ответ с кодом 200 и `Content-Type: application/dns-message`, в теле будет находиться такой же ответ, состоящий из байтов, как при работе по UDP. + +## DNSSEC +DNSSEC используется не для шифрования запросов, а для подписи конкретных доменов, чтобы защитить записи от подмены и типов атак "человек-посередине", на протяжении всего пути, от домена верхнего уровня, до конкретного домена может использоваться DNSSEC для валидации корректности домена. Для этого используются две ресурсные записи _DNSKEY_ и _RRSIG_. Для нормальной работы DNSSEC необходима ротация ключей, поэтому если вы держите свой DNS-сервер в этом может возникнуть проблема. Однако, некоторые, облачные DNS-серверы делают это автоматически, достаточно лишь включить эту опцию. + + +## Happy eyeballs + +Как только мы получаем AAAA-запись и A-запись, начинается процедура по определению, на какую из двух записей заходить, эта процедура называется happy eyeballs. + +Браузер отправляет специальные запросы на все пришедшие IP адреса и выясняет, если с IPv6 версии сайта пришёл ответ, то он отменяет все остальные проверки и заходит по этому адресу, в противном случае начинает тестировать IPv4 версию. Но все ОС сегодня делают упор на AAAA-запись. Данная проверка выполняется во всех современных браузерах и практически не занимает времени. + +## mDNS +_mDNS_ - протокол, реализующий работу DNS в локальных сетях без наличия сервера. Очень простыми словами, устройства в локальной сети берут своё имя, добавляют к нему домен `.local` и распространяет эту информацию о себе в сети, другие устройства получают эту информацию и записывают к себе, таким образом, организуется передача доменов для устройств поблизости, находясь в одной сети. + +## Форвардеры и резолверы + +- DNS-форвардер это сервер, берущий DNS-запросы клиентов перенаправляя на другой DNS-сервер. +Форвардеры необходимы для решения корпоративных нужд, например, внутренняя DNS-зона или для удобства/управления. +Как пример, домашние роутеры имеют встроенный DNS-форвардер. + +- DNS-резолвер это сервер, выполняющий рекурсивный поиск ресурсных записей, который мы разберём в пункте ниже. +Основные задачи DNS-резолвера, это снижение нагрузки на корневые серверы и другие NS-серверы, выполнение кеширования для повышения производительности. +Примерами DNS-резолверов можно назвать любые адреса [DNS-серверов](https://gist.github.com/mutin-sa/5dcbd35ee436eb629db7872581093bc5) в Интернете. + + +## Рекурсивный поиск записи (под капотом) + +Находясь дома, работая в Интернете, все наши DNS запросы обрабатывает либо маршрутизатор, либо оборудование провайдера или облачные DNS серверы компании Google или CloudFlare. Однако, мы разберём откуда они берут ответы на DNS-запросы. + + + +### Структура домена + +[//]: <> (Визуально нарисовать из чего состоит домен по описанию ниже, использовать реверсивную запись .ru.yandex.mail) + +Доменное имя имеет иерархичную структуру, где разделителем является символ "." (точка). Точка является и завершающим символом, хотя мы её и не пишем, она всегда присутствует, например `example.com.`. Для понимания иерархии, следует читать в обратном порядке, это мы сейчас и разберём. + +### Корневые серверы + +_Корневые серверы_ - DNS-серверы которые хранят в себе информацию о доменах первого (верхнего) уровня, таких как `.com`,`.org`,`.ru`,`.рф`. Они расположены в разных частях планеты, полный их список можно найти на [сайте IANA](https://www.iana.org/domains/root/files), а иногда и в вашей ОС по пути ` /usr/share/dns/root.hints`. + +При рабочем DNS, список можно запросить отправив NS запрос на один из серверов по символу "."(точка), например `dig @a.root-servers.net . NS` +
+ Ответ + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43584 +;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27 +;; WARNING: recursion requested but not available + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;. IN NS + +;; ANSWER SECTION: +. 518400 IN NS l.root-servers.net. +. 518400 IN NS j.root-servers.net. +. 518400 IN NS f.root-servers.net. +. 518400 IN NS h.root-servers.net. +. 518400 IN NS d.root-servers.net. +. 518400 IN NS b.root-servers.net. +. 518400 IN NS k.root-servers.net. +. 518400 IN NS i.root-servers.net. +. 518400 IN NS m.root-servers.net. +. 518400 IN NS e.root-servers.net. +. 518400 IN NS g.root-servers.net. +. 518400 IN NS c.root-servers.net. +. 518400 IN NS a.root-servers.net. + +;; ADDITIONAL SECTION: +l.root-servers.net. 518400 IN A 199.7.83.42 +l.root-servers.net. 518400 IN AAAA 2001:500:9f::42 +j.root-servers.net. 518400 IN A 192.58.128.30 +j.root-servers.net. 518400 IN AAAA 2001:503:c27::2:30 +f.root-servers.net. 518400 IN A 192.5.5.241 +f.root-servers.net. 518400 IN AAAA 2001:500:2f::f +h.root-servers.net. 518400 IN A 198.97.190.53 +h.root-servers.net. 518400 IN AAAA 2001:500:1::53 +d.root-servers.net. 518400 IN A 199.7.91.13 +d.root-servers.net. 518400 IN AAAA 2001:500:2d::d +b.root-servers.net. 518400 IN A 170.247.170.2 +b.root-servers.net. 518400 IN AAAA 2801:1b8:10::b +k.root-servers.net. 518400 IN A 193.0.14.129 +k.root-servers.net. 518400 IN AAAA 2001:7fd::1 +i.root-servers.net. 518400 IN A 192.36.148.17 +i.root-servers.net. 518400 IN AAAA 2001:7fe::53 +m.root-servers.net. 518400 IN A 202.12.27.33 +m.root-servers.net. 518400 IN AAAA 2001:dc3::35 +e.root-servers.net. 518400 IN A 192.203.230.10 +e.root-servers.net. 518400 IN AAAA 2001:500:a8::e +g.root-servers.net. 518400 IN A 192.112.36.4 +g.root-servers.net. 518400 IN AAAA 2001:500:12::d0d +c.root-servers.net. 518400 IN A 192.33.4.12 +c.root-servers.net. 518400 IN AAAA 2001:500:2::c +a.root-servers.net. 518400 IN A 198.41.0.4 +a.root-servers.net. 518400 IN AAAA 2001:503:ba3e::2:30 +``` +
+ +### Авторитетные серверы для доменов первого уровня +_Авторитетные серверы для доменов первого уровня_ - DNS-серверы на которые будут ссылаться корневые серверы для дальнейшего поиска конкретного домена. Проверим это командой `dig @2001:503:ba3e::2:30 ru. NS`, где мы у корневого сервера (`a.root-servers.net`) запросили NS-ы для домена первого домена `ru`, ответом будет + +
+ Ответ + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55540 +;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 11 +;; WARNING: recursion requested but not available + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;ru. IN NS + +;; AUTHORITY SECTION: +ru. 172800 IN NS a.dns.ripn.net. +ru. 172800 IN NS d.dns.ripn.net. +ru. 172800 IN NS f.dns.ripn.net. +ru. 172800 IN NS b.dns.ripn.net. +ru. 172800 IN NS e.dns.ripn.net. + +;; ADDITIONAL SECTION: +a.dns.ripn.net. 172800 IN A 193.232.128.6 +a.dns.ripn.net. 172800 IN AAAA 2001:678:17:0:193:232:128:6 +d.dns.ripn.net. 172800 IN A 194.190.124.17 +d.dns.ripn.net. 172800 IN AAAA 2001:678:18:0:194:190:124:17 +f.dns.ripn.net. 172800 IN A 193.232.156.17 +f.dns.ripn.net. 172800 IN AAAA 2001:678:14:0:193:232:156:17 +b.dns.ripn.net. 172800 IN A 194.85.252.62 +b.dns.ripn.net. 172800 IN AAAA 2001:678:16:0:194:85:252:62 +e.dns.ripn.net. 172800 IN A 193.232.142.17 +e.dns.ripn.net. 172800 IN AAAA 2001:678:15:0:193:232:142:17 +``` +
+ +И запросим тоже самое, но для punycode домена `рф`, командой `dig @2001:503:ba3e::2:30 xn--p1ai. NS` + +
+ Ответ c punycode + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17248 +;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 11 +;; WARNING: recursion requested but not available + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;рф. IN NS + +;; AUTHORITY SECTION: +рф. 172800 IN NS f.dns.ripn.net. +рф. 172800 IN NS a.dns.ripn.net. +рф. 172800 IN NS d.dns.ripn.net. +рф. 172800 IN NS b.dns.ripn.net. +рф. 172800 IN NS e.dns.ripn.net. + +;; ADDITIONAL SECTION: +f.dns.ripn.net. 172800 IN A 193.232.156.17 +f.dns.ripn.net. 172800 IN AAAA 2001:678:14:0:193:232:156:17 +a.dns.ripn.net. 172800 IN A 193.232.128.6 +a.dns.ripn.net. 172800 IN AAAA 2001:678:17:0:193:232:128:6 +d.dns.ripn.net. 172800 IN A 194.190.124.17 +d.dns.ripn.net. 172800 IN AAAA 2001:678:18:0:194:190:124:17 +b.dns.ripn.net. 172800 IN A 194.85.252.62 +b.dns.ripn.net. 172800 IN AAAA 2001:678:16:0:194:85:252:62 +e.dns.ripn.net. 172800 IN A 193.232.142.17 +e.dns.ripn.net. 172800 IN AAAA 2001:678:15:0:193:232:142:17 +``` +
+ +### Узнаём где находится конкретный домен +Теперь у нас есть информация о данных относительно домена первого уровня, обратившись к его серверам, мы можем узнать NS-серверы конкретного домена в этой доменной зоне, запросим информацию о NS-серверах домена `yandex.ru`, введя команду `dig @2001:678:17:0:193:232:128:6 yandex.ru. NS`, тут мы обратились по IP-адресу по домену `a.dns.ripn.net`, где `ripn.net` это адрес _Российского НИИ Развития Общественных сетей_, куда ссылаются домены первого уровня `ru`, `рф`, `su`. + +
+ Ответ + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42922 +;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 5 +;; WARNING: recursion requested but not available + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 1232 +;; QUESTION SECTION: +;yandex.ru. IN NS + +;; AUTHORITY SECTION: +YANDEX.RU. 345600 IN NS ns1.yandex.RU. +YANDEX.RU. 345600 IN NS ns2.yandex.RU. + +;; ADDITIONAL SECTION: +ns2.yandex.RU. 345600 IN AAAA 2a02:6b8:0:1::1 +ns1.yandex.RU. 345600 IN AAAA 2a02:6b8::1 +ns2.yandex.RU. 345600 IN A 93.158.134.1 +ns1.yandex.RU. 345600 IN A 213.180.193.1 +``` +
+ +### Запрашиваем конкретную информацию по домену +Теперь, мы нашли NS-серверы конкретного домена, и можем собрать все ресурсные записи, например, A,AAAA,MX, попробуем взять AAAA-запись у сайта `yandex.ru` командой `dig @2a02:6b8::1 yandex.ru AAAA`. + +
+ Ответ + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64108 +;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;yandex.ru. IN AAAA + +;; ANSWER SECTION: +yandex.ru. 600 IN AAAA 2a02:6b8:a::a +``` +
+ +Или же взять поддомен `dig @2a02:6b8::1 mail.yandex.ru AAAA` + +
+ Ответ + +``` +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36123 +;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;mail.yandex.ru. IN AAAA + +;; ANSWER SECTION: +mail.yandex.ru. 300 IN AAAA 2a02:6b8::a4 +``` +
+ +[//]: <> (Нарисовать схему со стрелочками: Корневые NS -> Авторитетные NS -> NS серверы домена -> A/AAAA/MX...-записи) + +Так был пройден весь путь запроса информации о домене. Путь выглядит сложным, но на каждом шаге нас встречали резервные адреса для повышения отказоустойчивости, ведь DNS один из самых важных протоколов в работе Интернета. + +Мы прошли весь путь и разобрали откуда и куда переходят запросы, однако, флаг `+trace` в утилите `dig` выдал бы этот путь автоматически, например команда `dig doka.guide +trace` уместила бы весь путь в один вывод команды. + +## Зарезервированные домены + +Некоторые домены являются зарезервированными для работы определённого ПО или в локальных сетях. Разберём небольшой, но самый важный список. + +| Название | Назначение | +|---------|------------| +| .in-addr.arpa | Частные сети для маппинга к PTR | +| .ip6.arpa | Частные сети для маппинга IPv6 адресов к PTR | +| .home.arpa | Небольшие локальные сети | +| .example, example.com, example.org, example.net | Примеры и документации | +| .test | Тестовые домены в документациях | +| .invalid | Указание ошибок в ответах через DNS | +| .localhost | Петли | +| .onion | Домены используемые в сетях Tor | +| .internal | Домены используемые во внутренних сетях | +| .local | Служба mDNS | + +[//]: <> (Это стоит делать очень ярко, если можете, сделайте! Очень частая ошибка.) + + +## Заключение + +Благодаря работе системы доменных имён, нам не нужно хранить огромные записные книжки с любимыми сайтами или встречаться с коллизиями, где у разных людей могли быть разные адреса для разных сайтов. diff --git a/tools/index.md b/tools/index.md index 2376683e81..a541943cd6 100644 --- a/tools/index.md +++ b/tools/index.md @@ -104,6 +104,7 @@ groups: - http-protocol - tcp-udp-protocols - ipv6-for-webdevs + - dns - name: Безопасность items: