Давайте уже разберемся в DNS

Original author: Pete Keen
  • Translation

image
Внимательный читатель найдет на этой картинке IPv6


Люди часто озадачены доменами. Почему мой сайт не работает? Почему эта хрень поломана, ничего не помогает, я просто хочу, чтобы это работало! Обычно, вопрошающий или не знает про DNS, или не понимает фундаментальных идей. Для многих DNS — страшная и непонятная штука. Эта статья — попытка развеять такой страх. DNS — это просто, если понять несколько базовых концепций.


Что такое DNS


DNS расшифровывается как Domain Name System. Это глобальное распределенное хранилище ключей и значений. Сервера по всему миру могут предоставить вам значение по ключу, а если им неизвестен ключ, то они попросят помощи у другого сервера.


Вот и все. Правда. Вы или ваш браузер запрашивает значение для ключа www.example.com, и получает в ответ 1.2.3.4.


Базовые штуки


Большой плюс DNS в том, что это публичная услуга, и можно потыкать в сервера если хочется разобраться. Давайте попробуем. У меня есть домен petekeen.net, который хостится на машине web01.bugsplat.info. Команды, используемые ниже, можно запустить из командной строки OS X (ой, то есть macOS, — прим. пер.).


Давайте взглянем на маппинг между именем и адресом:


$ dig web01.bugsplat.info

Команда dig это такой швейцарский армейский нож для DNS-запросов. Крутой, многофункциональный инструмент. Вот первая часть ответа:


; <<>> DiG 9.7.6-P1 <<>> web01.bugsplat.info
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51539
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

Здесь есть только одна интересная деталь: информация о самом запросе. Говорится, что мы запросили запись и получили ровно один ответ. Вот:


;; QUESTION SECTION:
;web01.bugsplat.info.       IN  A

dig по-умолчанию запрашивает A-записи. A это address (адрес), и это один из фундаментальных видов записей в DNS. A содержит один IPv4-адрес. Есть эквивалент для IPv6-адресов —  AAAA. Давайте взглянем на ответ:


;; ANSWER SECTION:
web01.bugsplat.info.    300 IN  A   192.241.250.244

Тут говорится, что у хоста web01.bugsplat.info. есть один адрес A192.241.250.244. Число 300 это TTL, или time to live (время жизни). Столько секунд можно держать значение в кэше до повторной проверки. Слово IN означает Internet. Так сложилось исторически, это нужно для разделения типов сетей. Подробнее об этом можно почитать в документе IANA's DNS Parameters.


Оставшаяся часть ответа описывает сам ответ:


;; Query time: 20 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Jul 19 20:01:16 2013
;; MSG SIZE  rcvd: 56

В частности, здесь говорится, как долго сервер откликался, какой у сервера IP-адрес (192.168.1.1), на какой порт стучался dig  (53, DNS-порт по-умолчанию), когда запрос был завершен и сколько байтов было в ответе.


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


Но в этом примере не видно, что DNS-сервер 192.168.1.1 связался с кучей других серверов чтобы ответить на простой вопрос: «куда указывает адрес web01.bugsplat.info?». Давайте запустим трейс чтобы узнать о всей возможной цепочке, которую пришлось бы пройти dig'у, если бы информация не был закэширована:


$ dig +trace web01.bugsplat.info

; <<>> DiG 9.7.6-P1 <<>> +trace web01.bugsplat.info
;; global options: +cmd
.           137375  IN  NS  l.root-servers.net.
.           137375  IN  NS  m.root-servers.net.
.           137375  IN  NS  a.root-servers.net.
.           137375  IN  NS  b.root-servers.net.
.           137375  IN  NS  c.root-servers.net.
.           137375  IN  NS  d.root-servers.net.
.           137375  IN  NS  e.root-servers.net.
.           137375  IN  NS  f.root-servers.net.
.           137375  IN  NS  g.root-servers.net.
.           137375  IN  NS  h.root-servers.net.
.           137375  IN  NS  i.root-servers.net.
.           137375  IN  NS  j.root-servers.net.
.           137375  IN  NS  k.root-servers.net.
;; Received 512 bytes from 192.168.1.1#53(192.168.1.1) in 189 ms

info.           172800  IN  NS  c0.info.afilias-nst.info.
info.           172800  IN  NS  a2.info.afilias-nst.info.
info.           172800  IN  NS  d0.info.afilias-nst.org.
info.           172800  IN  NS  b2.info.afilias-nst.org.
info.           172800  IN  NS  b0.info.afilias-nst.org.
info.           172800  IN  NS  a0.info.afilias-nst.info.
;; Received 443 bytes from 192.5.5.241#53(192.5.5.241) in 1224 ms

bugsplat.info.      86400   IN  NS  ns-1356.awsdns-41.org.
bugsplat.info.      86400   IN  NS  ns-212.awsdns-26.com.
bugsplat.info.      86400   IN  NS  ns-1580.awsdns-05.co.uk.
bugsplat.info.      86400   IN  NS  ns-911.awsdns-49.net.
;; Received 180 bytes from 199.254.48.1#53(199.254.48.1) in 239 ms

web01.bugsplat.info.    300 IN  A   192.241.250.244
bugsplat.info.      172800  IN  NS  ns-1356.awsdns-41.org.
bugsplat.info.      172800  IN  NS  ns-1580.awsdns-05.co.uk.
bugsplat.info.      172800  IN  NS  ns-212.awsdns-26.com.
bugsplat.info.      172800  IN  NS  ns-911.awsdns-49.net.
;; Received 196 bytes from 205.251.195.143#53(205.251.195.143) in 15 ms

Информация выводится в иерархической последовательности. Помните как dig вставил точку . после хоста, web01.bugsplat.info? Так вот, точка . это важная деталь, и она означает корень иерархии.


Корневые DNS-сервера обслуживаются различными компаниями и государствами по всему миру. Изначально их было мало, но интернет рос, и сейчас их 13 штук. Но у каждого из серверов есть десятки или сотни физических машин, которые прячутся за одним IP.


Итак, в самом верху трейса находятся корневые сервера, каждый определен с помощью NS-записи. NS-запись связывает доменное имя (в данном случае, корневой домен) с DNS-сервером. Когда вы регистрируете доменное имя у регистратора типа Namecheap или Godaddy, они создают NS-записи для вас.


В следующем блоке видно, как dig выбрал случайный корневой сервер, и запросил у него A-запись для web01.bugsplat.info. Видно только IP-адрес корневого сервера (192.5.5.241). Так какой именно корневой сервер это был? Давайте узнаем!


$ dig -x 192.5.5.241

; <<>> DiG 9.8.3-P1 <<>> -x 192.5.5.241
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2862
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;241.5.5.192.in-addr.arpa.  IN  PTR

;; ANSWER SECTION:
241.5.5.192.in-addr.arpa. 3261  IN  PTR f.root-servers.net.

Флаг -x заставляет dig провести обратный поиск по IP-адресу. DNS отвечает записью PTR, которая соединяет IP и хост, в данном случае — f.root-servers.net.


Возвращаясь к нашему начальному запросу: корневой сервер F вернул другой набор NS-серверов. Он отвечает за домен верхнего уровня infodig запрашивает у одного из этих серверов запись A для web01.bugsplat.info, и получает в ответ еще один набор NS-серверов, и потом запрашивает у одного из этих серверов запись A для web01.bugsplat.info.. И, наконец, получает ответ!


Уф! Сгенерировалось бы много трафика, но почти все эти записи были надолго закэшированы каждым сервером в цепочке. Ваш компьютер тоже кэширует эти данные, как и ваш браузер. Чаще всего DNS-запросы никогда не доходят до корневых серверов, потому что их IP-адреса почти никогда не изменяются («Наверно все таки речь идет о большом TTL для записей в их базе. Если у DNS сервера IP адрес вообще ни разу не изменялся, то это не означает, что его база навечно закеширована» — прим. от rrrav). Домены верхнего уровня comnetorg, и т.д. тоже обычно сильно закэшированы.


Другие типы


Есть еще несколько типов, о которых стоит знать. Первый это MX. Он соединяет доменное имя с одним или несколькими почтовыми серверами. Электронная почта настолько важна, что у нее есть свой тип DNS-записи. Вот значения MX для petekeen.net:


$ dig petekeen.net mx

; <<>> DiG 9.7.6-P1 <<>> petekeen.net mx
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18765
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;petekeen.net.          IN  MX

;; ANSWER SECTION:
petekeen.net.       86400   IN  MX  60 web01.bugsplat.info.

;; Query time: 272 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Jul 19 20:33:43 2013
;; MSG SIZE  rcvd: 93

Заметьте, что MX-запись указывает на имя, а не на IP-адрес.


Еще один тип, который вам скорее всего знаком, это CNAME. Расшифровываетя как Canonical Name (каноническое имя). Он связывает одно имя с другим. Давайте посмотрим на ответ:


$ dig www.petekeen.net

; <<>> DiG 9.7.6-P1 <<>> www.petekeen.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16785
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.petekeen.net.      IN  A

;; ANSWER SECTION:
www.petekeen.net.   86400   IN  CNAME   web01.bugsplat.info.
web01.bugsplat.info.    300 IN  A   192.241.250.244

;; Query time: 63 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Jul 19 20:36:58 2013
;; MSG SIZE  rcvd: 86

Сразу видно, что мы получили два ответа. Первый говорит, что www.petekeen.net указывает на web01.bugsplat.info. Второй возвращает запись A для того сервера. Можно считать, что CNAME это псевдоним (или алиас) для другого сервера.


Что не так с CNAME


Записи CNAME очень полезны, но есть важный момент: если есть CNAME с каким-то именем, то нельзя создать другую запись с таким же именем. Ни MX, ни A, ни NS, ничего.


Причина в том, что DNS производит замену таким образом, что все записи того места, куда указывает CNAME, также валидны для CNAME. В нашем примере, записи у www.petekeen.net и web01.bugsplat.info будут совпадать.


Поэтому нельзя делать CNAME на корневом домене вроде petekeen.net, потому что обычно там нужны другие записи, например, MX.


Запросы к другим серверам


Давайте представим, что конфигурация DNS испорчена. Вам кажется, что вы исправили проблему, но не хотите ждать когда обновится кэш чтобы удостовериться. С помощью dig можно сделать запрос к публичному DNS-серверу вместо своего дефолтного, вот так:


$ dig www.petekeen.net @8.8.8.8

Символ @ с IP-адресом или хостом заставляет dig прозводить запрос к указанному серверу через порт по-умолчанию. Можно использовать публичный DNS-сервер Гугла или почти-публичный-сервер Level 3 по адресу 4.2.2.2.


Типичные ситуации


Давайте рассмотрим типичные ситуации, знакомые многим веб-разработчикам.


Редирект домена на www

Часто нужно сделать редирект домена iskettlemanstillopen.com на www.iskettlemanstillopen.com. Регистраторы типа Namecheap или DNSimple называют это URL Redirect. Вот пример из админки Namecheap:



Символ @ означает корневой домен iskettlemanstillopen.com. Давайте посмотрим на запись A у этого домена:


$ dig iskettlemanstillopen.com
;; QUESTION SECTION:
;iskettlemanstillopen.com.  IN  A

;; ANSWER SECTION:
iskettlemanstillopen.com. 500   IN  A   192.64.119.118

Этот IP принадлежит Namecheap'у, и там крутится маленький веб-сервер, который просто делает перенаправление на уровне HTTP на адрес http://www.iskettlemanstillopen.com:


$ curl -I iskettlemanstillopen.com
curl -I iskettlemanstillopen.com
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Fri, 19 Jul 2013 23:53:21 GMT
Content-Type: text/html
Connection: keep-alive
Content-Length: 154
Location: http://www.iskettlemanstillopen.com/

CNAME для Heroku или Github


Взгляните на скриншот выше. На второй строке там CNAME. В этом случае www.iskettlemanstillopen.com указывает на приложение, запущенное на Heroku.


$ heroku domains
=== warm-journey-3906 Domain Names
warm-journey-3906.herokuapp.com
www.iskettlemanstillopen.com

С Github похожая история, но там нужно создать специальный файл в корне репозитория, и назвать его CNAME. См. документацию.


Wildcards


Большинство DNS-серверов поддерживают шаблоны (wildcards). Например, есть wildcard CNAME для *.web01.bugsplat.info указывает на web01.bugsplat.info. Тогда любой хост на web01 будет указывать на web01.bugsplat.info и не нужно создавать новые записи:


$ dig randomapp.web01.bugsplat.info

;; QUESTION SECTION:
;randomapp.web01.bugsplat.info. IN  A

;; ANSWER SECTION:
randomapp.web01.bugsplat.info. 300 IN CNAME web01.bugsplat.info.
web01.bugsplat.info.    15  IN  A   192.241.250.244

Заключение


Надеюсь, теперь у вас есть базовое понимание DNS. Все стандарты описаны в документах:



Есть еще пара интересных RFC, в том числе 4034, который описывает стандарт DNSSEC и 5321, который описывает взаимосвязь DNS и email. Их интересно почитать для общего развития.

Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 34

    +2
    В избраное!
    Кидать «сисадминам» которые не понимают что такое CNAME и куда его прописать, а от MX вообще впадают в ступор, но на ссылку на вики почему-то обежаются.
      0
      tools.ietf.org/html/rfc1034 или не пущать!
        0
        Серьёзно? Даже такой недосисадмин как я, знает что такое MX и CNAME
          0

          Увы, но мне лично несколько раз выпадала честь проводить ликбез на пальцах, по телефону, сисадминам достаточно крупных региональных организаций. (Часто они не в курсе как работает то что настроил их предшественник)


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


          P.S.: Сам я сисадмин веб-студии, и общаюсь обычно по выкладке сайтов и о том что бы при это не отвалилась почта и прочие.

            0
            Жесть.
            Как такие люди попадают на работу? По знакомству штоле?
              0

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


              Судя по профилю вы старше меня и сами думаю, видели достаточно кадров...


              Впрочем и сам я человек без образования, с весьма странным набором навыков, скорее дилетанта широкого профиля чем профессионала. Работаю сисадмином, dev-ops'ом, программером, по чуть чуть...

        +5
        URL Redirect — это не совсем DNS, это хак с отдельным сервером.
        Лучше поднять у себя сервер, слушающий домен с www на 80 и 443 портах, и переадресовывающий 301 редиректом

        Пример для nginx
        # http -> https
        server {
        	server_name		example.org;
        	listen			80;
        	return 301 https://example.org$request_uri;
        }
        # www -> non-www
        server {
        	server_name     www.example.org;
        	listen		80;
        	listen      	443 ssl;
        	
        	ssl_certificate      		/etc/ssl/example.org.crt;
        	ssl_certificate_key  		/etc/ssl/example.org.key;
        	
        	return 301 https://example.org$request_uri;
        }
        # main
        server {
        	server_name	example.org;
        	listen      	443 ssl http2;
        .....
        }
        

          0
          Да, тут автор просто описывает типичный сценарий конкретно из Namecheap образца 2013 года :)
            0
            Или можно воспользоваться публичным сервисом редиректа, прописав 174.129.25.170 (http://wwwizer.com/naked-domain-redirect).
            Удобно в случае если домен привязывается к Гугл Сайтам или Гугл Блогам, где привязать можно только поддомен.
            0
            Про CNAME более правильным примером были бы записи NS, без которых не может быть зона (домен второго уровня например). MX-то чёрт с ними.
              +2
              Поэтому нельзя делать CNAME на корневом домене вроде petekeen.net, потому что обычно там нужны другие записи, например, MX.

              Для этого продвинутые ДНС-хостеры (например zilore.com dnsimple.com) придумали ALIAS записи, которые позволяют добавить CNAME запись в корневой домен, а внутри она будет автоматически преобразована в А запись и поддерживаться в актуальном состоянии.
                +1
                есть у меня один домен, лежит в Яндекс.ПДД, однажды. еще не зная, что CNAME для самого домена прописывать нельзя, я взял и прописал, и оно почему-то сохранилось, и работает до сих пор как-то :) не знаю, может потому, что домен в .net.ru., и система восприняла его как поддомен.
                позже, с другим домен хотел сделать тоже самое, а интерфейс Яндекса уже ошибку выдаёт. писал тогда по этому поводу в техподдержку, и тогда-то мне и сказали, что нельзя
                  0
                  Оно в среднем работать-то будет. Но шаг вправо-влево и результат непредсказуем.
                    0
                    тоже так подумал, поэтому больше эту запись не трогаю, наверняка сохранить уже не даст
                      0
                      Из недавнего, уж не знаю что меня на это сподвигло.
                    0
                    О, крутая тема
                    0
                    >> Заметьте, что MX-запись указывает на домен, а не на IP-адрес.
                    может на хост?
                      0
                      Да, вы правы. Я изменил на «имя», так ближе к оригиналу и тоже правильно :)
                      +8
                      Статья, вроде, для начинающих. Все подробно разжевывается, при этом автор вдруг вводит термины «A-запись» и «NS-сервер» и начинает на их основе что-то объяснять. В итоге все остальное для новичка выглядит полной белибердой. Ибо что это за А-запись и где B,C,D...Z-записи и зачем нужен NS сервер если уже есть DNS сервер — так и остается для читателя тайной. Гугл, конечно, никто не отменял, но очень велика вероятность, что по запросу этих терминов он выведет на более последовательные статьи для начинающих.
                        –1
                        Новичкам лучше рассказать про hosts файл, чтобы они не покупали себе домены, а поднимали веб сервер локально, через hosts делали виртуальные домены и там игрались.

                        Если же новички захотят поднять свой DNS сервер, могут попасть под уязвимость, когда можно послать небольшой запрос, а ответ на него будет уходить целевой жертве, причем весьма большим.
                        Таким образом, без всяких вирусов, без установки ботнета, просто получив список открытых (неправильно настроенных DNS серверов), можно через них быстро организовать кому-нибудь ddos.
                          +3
                          DDOS — это, конечно, круто. Но я вот хотел уже разобраться с DNS, но на фразе
                          Причина в том, что DNS производит замену таким образом, что все записи того места, куда указывает CNAME, также валидны для CNAME. В нашем примере, записи у www.petekeen.net и web01.bugsplat.info будут совпадать.
                          Мой мозг завернулся в CNAME и перестал отвечать. Серьезно, я вообще не понял, о чем речь. И ведь все статьи такие: получаем адрес по имени, корневые сервера, иерахия, все понятно вроде, и тут херак, и MX запись на AAAA реестр
                          O_o
                        0
                        >>Часто нужно сделать редирект домена iskettlemanstillopen.com на www.iskettlemanstillopen.com.

                        Лучше делать наоборот.

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

                        Например, там есть инструменты для организации загрузки операционных систем по сети, также там можно хранить данные авторизации, да вообще чего только нельзя хранить.
                          +2
                          Логика работы DNS проста и понятна, то, как софт интерпретирует ресурсные записи, расположенные в DNS, к сложности самого протокола не имеет никакого отношения.

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

                          Самые ходовые А, АААА (А6), CNAME, PTR, SRV, MX, TXT.
                          Ну и «технические» NS, SOA

                          При этом софта, который использует специально оформленные TXT или SRV поля много-много больше и каждый ведёт себя по-разному (и не всегда логично).
                          Но сложность ли это DNS? Ничуть.

                          DNSSEC — уже сложнее, но он и куда бОльший функционал несёт, хотя тоже вполне прост и понятен в большинстве случаев.
                          +1
                          Вместо тысячи слов: www.amazon.com/DNS-BIND-5th-Cricket-Liu/dp/0596100574
                            0
                            Есть и перевод — http://www.books.ru/books/dns-i-bind-5-e-izdanie-552030/
                            +1
                            Чаще всего DNS-запросы никогда не доходят до корневых серверов, потому что их IP-адреса почти никогда не изменяются.

                            Наверно все таки речь идет о большом TTL для записей в их базе. Если у DNS сервера IP адрес вообще ни разу не изменялся, то это не означает, что его база навечно закеширована.
                              0
                              И ни слова про смену IP-адреса при переезде и его зависимость от коряво настроенных DNS-серверов игнорирующих TTL.
                                0

                                И про glue records при использовании NS в рамках того же домена, что порой ещё больнее бывает при переезде NS.

                                0
                                Тоже не совсем понял этот момент в оригинале.
                                Most of the time DNS resolution will never touch the root servers because their IP addresses hardly ever change.


                                Добавил ваше замечание в пост. Спасибо!
                                  0
                                  Ага, и в оригинале тоже звучит неоднозначно — множественные формы как для корневых серверов, так и для IP адресов позволяют отнести понятие (большое TTL) как к IP адресам серверов, так и IP адресам в базе. Такой вот семантический прокол в документации — хорошо, что это не кредитный договор…
                                0
                                Еще больше напугал :)
                                  0
                                  статья нужная. но для совсем новичков, которым свой dns поднимать не надо, а надо на самом простом уровне уметь понять где проблема при разрыве связности, она слишком уходит в ненужные детали. И потому становится слишком сложной, заумной и ненужной. А для админов, которым хоть как-то надо поднять хоть минимальный dns-сервер ее катострофически мало. нет ни слова ни про ns, ни про soa. Так что админу от статьи точно пользы нет, на основании этих данных сервер не поднять никак :(
                                    0
                                    Ну так это и не пошаговая инструкция для поднятия DNS-сервера.
                                    0

                                    В список RFC можно ещё добавить 1912 "Common DNS Operational and Configuration Errors".

                                    Only users with full accounts can post comments. Log in, please.