Я много пишу о технологиях, которые показались мне сложными. Недавно моя подруга Сумана задала мне интересный вопрос – почему все эти вещи так сложно изучать? Почему они кажутся такими загадочными?

Для примера возьмём DNS. Мы пользуемся DNS с 80-х (больше 35 лет!). Он применяется на каждом веб-сайте Интернета. И он довольно стабилен – во многих смыслах он работает точно так же, как делал это тридцать лет назад.

Но мне понадобились ГОДЫ, чтобы понять, как с уверенностью отлаживать проблемы с DNS, и я видела множество программистов, тоже испытывавших трудности с отладкой DNS. Что же происходит?

Я приведу пару своих рассуждений о том, почему устранять проблемы DNS трудно.

(В этом посте я не буду глубоко объяснять DNS, подробности о его работе см. в моей статье Implement DNS in a Weekend или в других моих постах о DNS.)

Большая часть системы спрятана

Когда вы делаете DNS-запрос на своём компьютере, в целом это выглядит так:

  1. Ваш компьютер делает запрос к серверу, называемому ресолвером

  2. Ресолвер проверяет свой кэш и делает запросы к каким-то другим серверам, называемым полномочными серверами доменных имён

А вот, чего вы не видите:

  • Кэш ресолвера. Что в нём находится?

  • Какой код библиотеки на вашем компьютере делает DNS-запрос (это  getaddrinfo из libc? Если так, то это getaddrinfo из glibc, или musl, или apple? Это код DNS вашего браузера? Это другая специальная реализация DNS?). Все эти варианты ведут себя немного по-своему и имеют разную конфигурацию, методики кэширования, функции и так далее. Например, до начала 2023 DNS musl не поддерживал TCP. 

  • Общение между ресолвером и полномочными серверами доменных имён. Думаю, многие проблемы с DNS было бы НАМНОГО проще понять, если бы мы волшебным образом получили трассировку того, какие полномочные серверы были опрошены вниз по потому во время вашего запроса, и информацию о том. что они сказали. (Например, что, если бы вы выполнили dig +debug google.com и получили бы кучу дополнительной отладочной информации?)

Как справляться со скрытыми системами

Пара идей о том, как работать со скрытыми системами

  • Просто объяснив людям, что такое скрытые системы, вы существенно упростите задачу. Долгое время я не представляла, что на моём компьютере есть множество разных библиотек DNS, которые использовались в разных ситуациях, и меня буквально годами сбивало это с толку. Это важная часть моего подхода к обучению.

  • В Mess With DNS мы попробовали методику "аквариума", демонстрирующую некоторые части системы (общение с ресолвером и полномочным сервером доменных имён), которые в обычном случае скрыты

  • Мне кажется, было бы невероятно круто расширить DNS, включив в него раздел отладочной информации. (Дополнение: похоже, он уже существует! Это называется Extended DNS Errors (EDE), а в инструменты постепенно добавляется его поддержка).

Мне нравится Extended DNS Errors

Extended DNS Errors - это новый способ, которым DNS-серверы могут передавать дополнительную отладочную информацию в DNS-ответах. Вот пример того, как это выглядит:

$ dig @8.8.8.8 xjwudh.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 39830
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; EDE: 12 (NSEC Missing): (Invalid denial of existence of xjwudh.com/a)
;; QUESTION SECTION:
;xjwudh.com.			IN	A
;; AUTHORITY SECTION:
com.			900	IN	SOA	a.gtld-servers.net. nstld.verisign-grs.com. 1690634120 1800 900 604800 86400
;; Query time: 92 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Sat Jul 29 08:35:45 EDT 2023
;; MSG SIZE  rcvd: 161

Я запросила несуществующий домен и получила расширенную ошибку EDE: 12 (NSEC Missing): (Invalid denial of existence of xjwudh.com/a). Не совсем понимаю, что это значит (это как-то связано с DNSSEC), но здорово, что существуют такие дополнительные отладочные сообщения.

Чтобы это заработало, мне пришлось установить более новую версию dig.

Запутанные инструменты

Хотя многое из связанного с DNS спрятано, существуют разные способы разобраться в происходящем при помощи dig.

Например, можно использовать dig +norecurse, чтобы узнать, есть ли у конкретного DNS-ресолвера конкретная запись в кэше. Похоже, если ответ не кэширован, то 8.8.8.8 возвращает ответ SERVFAIL.

Вот как это выглядит для google.com

$ dig +norecurse  @8.8.8.8 google.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11653
;; flags: qr ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com.			IN	A
;; ANSWER SECTION:
google.com.		21	IN	A	172.217.4.206
;; Query time: 57 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Jul 28 10:50:45 EDT 2023
;; MSG SIZE  rcvd: 55

А вот как для homestarrunner.com:

$ dig +norecurse  @8.8.8.8 homestarrunner.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 55777
;; flags: qr ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;homestarrunner.com.		IN	A
;; Query time: 52 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Jul 28 10:51:01 EDT 2023
;; MSG SIZE  rcvd: 47

Здесь мы видим обычный ответ NOERROR для google.com (который находится в кэше 8.8.8.8), но SERVFAIL для homestarrunner.com (которого в кэше нет). Это не значит, что DNS-записи homestarrunner.com нет (она есть!), просто она не кэширована.

Но если вы не привыкли, то чтение такого результата сбивает с толку! Вот некоторые из его аспектов, которые кажутся мне странными:

  1. Странные заголовки (есть->>HEADER<<-flags:OPT PSEUDOSECTION:QUESTION SECTION:ANSWER SECTION:)

  2. Странная расстановка пробелов (почему между OPT PSEUDOSECTION и QUESTION SECTION нет символа новой строки?)

  3. MSG SIZE rcvd: 47 странен (есть ли другие поля в MSG SIZE , за исключением rcvd? Какие?)

  4. В ответе говорится, что в разделе ADDITIONAL есть одна запись, но нам её не показывают; мы каким-то волшебным образом должны знать, что запись "OPT PSEUDOSECTION" на самом деле находится в дополнительном разделе.

В целом результаты работы dig создают впечатление специфического скрипта, который разрастался органически, а не проектировался намеренно.

Как справляться с запутанными инструментами

Вот несколько мыслей по улучшению запутанных инструментов:

  • Объясняйте вывод. Например, я написала статью о пользовании dig, где объяснила, как работает вывод dig и как настроить его, чтобы по умолчанию вывод был более кратким

  • Создавайте новые, более удобные инструменты. Например, для DNS есть dogdoggo и мой инструмент поиска dns. Я считаю их очень крутыми, но сама ими не пользуюсь, потому что иногда мне нужно сделать что-то чуть более сложное (наподобие использования +norecurse), а, насколько я знаю, ни dog, ни doggo не поддерживают +norecurse. Я лучше буду использовать для всего один инструмент, поэтому остаюсь с dig. Заменить широту функций dig будет очень сложно.

  • Сделайте вывод dig чуть более понятным. Если бы я лучше понимала программирование на C, то написала бы пул-реквест dig, добавляющий флаг +human , форматирующий вывод в длинном виде более структурированным и читаемым образом, например, как-то так:

$ dig +human +norecurse  @8.8.8.8 google.com
HEADER:
opcode: QUERY
status: NOERROR
id: 11653
flags: qr ra
records: QUESTION: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
QUESTION SECTION:
google.com.			IN	A
ANSWER SECTION:
google.com.		21	IN	A	172.217.4.206
ADDITIONAL SECTION:
EDNS: version: 0, flags:; udp: 512
EXTRA INFO:
Time: Fri Jul 28 10:51:01 EDT 2023
Elapsed: 52 msec
Server: 8.8.8.8:53
Protocol: UDP
Response size: 47 bytes

Это делает структуру DNS-ответа более понятной – тут есть заголовок, вопрос, ответ и дополнительный раздел.

При этом объяснение не становится более глупым! Это точно та же информация, только отформатированная более структурированно. Больше всего альтернативные инструменты DNS раздражают меня тем, что ради понятности удаляют информацию. И хотя эти инструменты определённо имеют свою сферу применения, я-то хочу видеть всю информацию! Мне просто нужно, чтобы она была донесена чётко.

За последние сорок лет мы многое узнали о проектировании более удобных для пользователей инструментов командной строки, и я думаю, было бы здорово применить эти знания к старым инструментам.

dig +yaml

Краткое примечание о dig: в новых версиях dig есть формат вывода +yaml , который мне кажется более понятным, однако на мой взгляд он слишком многословен (довольно простой DNS-ответ не помещается у меня на экране).

Странные особенности

В DNS есть странные аспекты, с которыми достаточно легко столкнуться, но почти невозможно разобраться, потому что никто не говорит тебе, что происходит. Вот несколько примеров (в моей статье Some ways DNS can break есть и другие):

  • негативное кэширование! (о котором я говорила в этом докладе) Мне понадобилось пять лет, чтобы осознать, что не стоит посещать домен для которого ещё нет записи DNS, потому что в таком случае будет кэшировано отсутствие такой записи, а это кэшируется на несколько часов, что очень раздражает.

  • Различия в реализациях getaddrinfo: до начала 2023 года musl не поддерживал TCP DNS

  • Ресолверы, игнорирующие TTL: если задать TTL для своих записей DNS (например, "5 минут"), некоторые ресолверы полностью игнорируют такие TTL и кэшируют записи на более долгий срок, возможно, на 24 часа

  • Если неправильно настроить nginx (вот так), но он будет кэшировать записи DNS бесконечно.

  • ndots может замедлить DNS Kubernetes

Как справляться со странными особенностями

По этому пункту у меня нет чётких ответов, но знания о странных особенностях получать чрезвычайно сложно (повторюсь, мне понадобились годы, чтобы разобраться с негативным кэшированием!), и мне кажется очень глупым, что люди продолжают открывать их для себя снова, и снова, и снова.

Некоторые мысли:

  • Невероятно полезно, когда люди чётко говорят о странностях при объяснении темы. Например, (на секунду забудем о DNS) во введении в Flexbox Джоша Комо объясняется тонкий момент о минимальном размере, с которым я сталкивалась ОЧЕНЬ много раз за долгие годы, прежде чем нашла объяснение происходившему.

  • Мне бы хотелось видеть больше общественных сборников подобных распространённых странностей. Например, shellcheck – это потрясающая коллекция тонкостей и особенностей bash.

Сложность документирования странного поведения DNS заключается в том, что разные люди будут сталкиваться с разными странностями – если вы просто конфигурируете DNS для личного домена раз в три года, то вы, скорее всего, столкнётесь с иными странностями, чем тот, кто администрирует DNS для домена с большим трафиком.

Пара более распространённых причин:

Редкость использования

Многие люди имеют дело с DNS чрезвычайно редко. И, конечно, если вы имеете дело с DNS раз в три года, её будет гораздо сложнее изучить!

Я думаю, в этом могут сильно помочь шпаргалки (например, "поэтапное изменение серверов доменных имён").

Трудности с экспериментами

С DNS бывает сложно экспериментировать – вам не захочется портить свой домен. Но мы создали Mess With DNS, чтобы немного упростить эту задачу.

На сегодня всё

Мне бы хотелось услышать ваши мысли о том, из-за чего DNS (или другую вашу любимую загадочную технологию) так сложно изучать.

Комментарии (11)


  1. vilgeforce
    04.08.2023 08:40
    +1

    DNS - старый протокол. Если его изучить, видно как люди экономили не то что отдельные байты, но даже биты! Взять хотя бы способ, которым имена в ответах записываются. Плюс изначально DNS не имел всех тех фич, которые есть сейчас. В итоге это сложный для понимания и парсинга протокол со своими "особенностями", подводными камнями и удивительными вещами.


  1. nick-for-habr
    04.08.2023 08:40
    +4

    А всё потому, что в очередной раз наступили на одни и те же грабли: взяли старый, простой как палка протокол, и начали его переусложнять. Причём переусложнение делается разными группами, с разными (часто пересекающимися) целями, без какого-то контроля и единого плана.

    Вот есть у нас DNS, он "просто работает". ААА, ужос - несекурно же! Ок, запилили "DNS secure" - пользуйтесь. Фи, сложно... Мы ща сами запилим безопасность! Получите ещё и HTTPS или TLS на выбор, теперь у вас уже целых три "безопасных" протокола: всё инклюзивно, как сейчас модно! Ну а что админы вешаются - да кому это интересно, главное что очередной гугл продвинул свой собственный "стандартик": ставьте Хром и будет вам счастье.

    FTP? Он то же слишком простой, давайте его обезопасим! Вжух - и теперь у вас есть ещё и FTPS и SFTP на выбор, радуйтесь! Что, ничего не работает? Ну так это вы устарели, фу таким быть. Ставьте хром пользуйтесь вот этой одной программой, и всё будет хорошо!

    А, ещё получите HTTPS. Что значит "не просили"?! Мы лучше знаем, что вам надо - не спорьте. А противный слишком простой HTTP мы запретим, во имя светлого будущего! Да, и не забудьте поставить Хром - только в нём "всё работает хорошо быстро" © (не является публичной офертой).

    Как-то так )))


    1. dartraiden
      04.08.2023 08:40
      +5

      Я не мастак в хихишечки, поэтому пройдусь по матчасти:


      Вот есть у нас DNS, он "просто работает".

      Черта с два он просто работает. Провайдеры типа "Дом.ру" не позволят вам пульнуть DNS-запрос на произвольный сервер. Они принудительно перехватывают его и отвечают вам сами. И если этот запрос про домен, доступа к которому, по мнению надзорного органа, вы иметь не должны, вместо адреса домена вы получите адрес заглушки провайдера с текстом "Не рыпайся, не положено".


      Ух, как классно работает!


      Ок, запилили "DNS secure" — пользуйтесь. Фи, сложно… Мы ща сами запилим безопасность! Получите ещё и HTTPS или TLS на выбор, теперь у вас уже целых три "безопасных" протокола: всё инклюзивно, как сейчас модно!

      Сложность тут не при чём. DoH/DoT были созданы, потому что DNSSEC решает лишь задачу "обеспечить защиту от подделки", но не скрывает содержимое запросов. Он такого не умеет в принципе, потому что создавался в гораздо более травоядные времена, чем сейчас.


      FTP? Он то же слишком простой, давайте его обезопасим! Вжух — и теперь у вас есть ещё и FTPS и SFTP на выбор, радуйтесь!

      SFTP не имеет никакого отношения к FTP.


      А, ещё получите HTTPS. Что значит "не просили"?!

      Сейчас бы в постсноуденовскую эпоху топить против HTTPS. Впрочем, и до Сноудена были свидетельства того, что нас слушают все, кому не лень, но уж после него стало очевидным, что слушают все и всех. А я, например, живу в стране, где всего лишь за простые два слова лишают месячной зарплаты, а за неоднократные залёты подобного рода отправляют в колонию.


      1. nick-for-habr
        04.08.2023 08:40

        Про "хихишечки" напомнило мем про "когда прошло уже 15 минут, а ты не сказал никому ни разу, что ты веган". Ах да, вы же не мастак в этом - сорян ;)

        Черта с два он просто работает. Провайдеры типа "Дом.ру" не позволят вам пульнуть DNS-запрос на произвольный сервер <...>

        Какое отношение к простоте работы протокола DNS имеют действия вашего провайдаре по злонамеренному искажению/изменению его функционала?

        С таким же успехом блокировку доступа к сайту целиком по его IP-адресу со стороны Роскомнадщора можно объявить недостатком протокола HTTPS. Ну а что? Ну или если свич сгорел, и "интернета нету" - это то же из-за того, что DNS "не работает", правильно? Ведь не работает же DNS?

        SFTP не имеет никакого отношения к FTP

        Ой, ну да ладно... Он для передачи файлов? Для передачи. В названии есть *FTP*? Есть. Значит имеет отношение.

        А то следуя вашей логике - то и DNS over HTTPS/TLS то же никакого отношения к DNS не имеет. Ибо только решает аналогичную задачу разрешения имени в IP, а под капотом - там вообще всё другое.

        Другие порты, протоколы - всё. Но DNS жеж? То то.

        Остальные криптоужасы про "кровавую гебню"... Если вы любите воблу - то либо любите её молча, либо любите её в другом месте, либо - если любовь горит в груди, и нет сил молчать (я серьёзно, без хихишечек) - то будьте готовы принять все последствия публичной любви к вобле в мире пусть и виртуальном, но уже - в реальном (это про последствия). Увы, ни HTTPS, ни DoH/DoT вас от последствий не оградят никак.

        Жизнь такая, реальность. Да и какой прок будет для воблы, если вы объяснитесь в любви к ней стыдливо-анонимно через три VPN-на? Никакого проку не будет, самообман один. Протухнет ваша вобла от любви такой анонимной.

        Это я не к тому, что вобла плохая - норм рыба, хотя мне больше тарань по душе. А к тому, что иллюзия безопасности - сильно хуже пусть и опасности, но которую знаешь и к которой готов.

        Ставьте Хром Всем пис ;)


  1. censor2005
    04.08.2023 08:40
    +2

    dig @8.8.8.8 domain.name +trace прекрасно помогает определить источник проблемы, и дальше уже точечно её решать


    1. alexxz
      04.08.2023 08:40
      +1

      Собственно, читая статью, я и ожидал увидеть этот флаг. Добавляешь его и видишь всю цепочку... Один флаг и вот ответ.


  1. Alexey2005
    04.08.2023 08:40
    +1

    Сложно изучать по причине отсутствия вменяемой документации и нормальных учебников. То, что есть, оно либо безнадёжно устарело, либо слишком поверхностно.
    Описывается "сферический DNS в вакууме" вместо конкретных наиболее распространённых нюансов его реализации и основных практик, используемых наиболее крупными провайдерами/хостерами. В итоге под 80% всей информации приходится собирать по крупицам, часто путём экспериментов.


  1. buldo
    04.08.2023 08:40

    А есть ли способ узнать какие поддомены есть у конкретного домена?

    Когда пытался найти ответ на этот вопрос, ничего не обнаружил


    1. DaemonGloom
      04.08.2023 08:40

      Нет. Можно только найти в поисковиках те, которые засветились там.
      Физически протокол для получения всех поддоменов есть, но используется только для синхронизации зон между ns серверами, отвечающими за конкретный домен. Пользователям он недоступен.


  1. PnDx
    04.08.2023 08:40

    К сожалению, данная заметка Юлии чересчур поверхностная и может вводить в заблуждение.

    Например, про вызов getaddrinfo(). Из "заметок на полях":

    • Если на запрашивающем хосте запущен nscd, все ответы кэшируются на 60с и
      подставляются в запросы "getaddrinfo()" через перехват стандартной
      функции. А этот глюкодром до сих пор стартует "искаропки" на моей любимой openSUSE. Но нет худа без добра: в 2016 году nscd помешал кой-чего проэксплуатировать. В том самом getaddrinfo() из тогдашней glibc. …Понятно что при этом RR ломается.

    • Сам getaddrinfo() таки делает RR. Но вот сюрприз: какой-то шибко-вумный программист разбил возвращаемые записи по "классам". Как я помню (сейчас лень искать), там как-то считается "удалённость" адресов и RR выполняется для "равноудалённых".

    Вообще, касающиеся DNS RFC достаточно конкретные, но да, чересчур обширные. И продолжают выходить новые правки. И это весьма стимулирует "юных DNS-писателей" (сам такой, было дело) забивать на "ненужные" подробности. Как пример, яндексовские резолверы. (По-русски их принято писа́ть через "з", по аналогии с "резолюцией.) Кто-то когда-то написал как понимал, а потом видимо пошёл заниматься ещё чем-то. И теперь некому найти/исправить "вечный кэш" для glue-записей. (Моя контора посылала им разбор, но в итоге была послана обратно.)

    Oops… Про RR держал в уме ещё вот эту заметку той же Юлии. Это там она жаловалась что "round robin DNS doesn’t work with getaddrinfo".


    1. AlexGluck
      04.08.2023 08:40

      На днс РР никогда не работал, сейчас потихоньку двигаются к исправлению этого, но только идиоты пытаются сделать РР на днс сегодня.