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. Их интересно почитать для общего развития.

Поделиться с друзьями
-->

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


  1. findoff
    16.06.2016 15:04
    +2

    В избраное!
    Кидать «сисадминам» которые не понимают что такое CNAME и куда его прописать, а от MX вообще впадают в ступор, но на ссылку на вики почему-то обежаются.


    1. chupasaurus
      16.06.2016 15:44

      tools.ietf.org/html/rfc1034 или не пущать!


    1. Okloks
      22.06.2016 05:46

      Серьёзно? Даже такой недосисадмин как я, знает что такое MX и CNAME


      1. findoff
        22.06.2016 08:31

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


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


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


        1. Okloks
          22.06.2016 11:46

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


          1. findoff
            22.06.2016 12:03

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


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


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


  1. istui
    16.06.2016 15:50
    +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;
    .....
    }
    


    1. freetonik
      16.06.2016 15:58

      Да, тут автор просто описывает типичный сценарий конкретно из Namecheap образца 2013 года :)


    1. alsopub
      16.06.2016 21:04

      Или можно воспользоваться публичным сервисом редиректа, прописав 174.129.25.170 (http://wwwizer.com/naked-domain-redirect).
      Удобно в случае если домен привязывается к Гугл Сайтам или Гугл Блогам, где привязать можно только поддомен.


  1. schors
    16.06.2016 16:09

    Про CNAME более правильным примером были бы записи NS, без которых не может быть зона (домен второго уровня например). MX-то чёрт с ними.


  1. mnasonov
    16.06.2016 16:59
    +2

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

    Для этого продвинутые ДНС-хостеры (например zilore.com dnsimple.com) придумали ALIAS записи, которые позволяют добавить CNAME запись в корневой домен, а внутри она будет автоматически преобразована в А запись и поддерживаться в актуальном состоянии.


    1. shumaher86
      16.06.2016 17:19
      +1

      есть у меня один домен, лежит в Яндекс.ПДД, однажды. еще не зная, что CNAME для самого домена прописывать нельзя, я взял и прописал, и оно почему-то сохранилось, и работает до сих пор как-то :) не знаю, может потому, что домен в .net.ru., и система восприняла его как поддомен.
      позже, с другим домен хотел сделать тоже самое, а интерфейс Яндекса уже ошибку выдаёт. писал тогда по этому поводу в техподдержку, и тогда-то мне и сказали, что нельзя


      1. schors
        16.06.2016 23:33

        Оно в среднем работать-то будет. Но шаг вправо-влево и результат непредсказуем.


        1. shumaher86
          16.06.2016 23:51

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


        1. navion
          17.06.2016 01:41

          Из недавнего, уж не знаю что меня на это сподвигло.


    1. schors
      16.06.2016 23:32

      О, крутая тема


  1. vrough
    16.06.2016 17:14

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


    1. freetonik
      16.06.2016 17:14

      Да, вы правы. Я изменил на «имя», так ближе к оригиналу и тоже правильно :)


  1. Loki3000
    16.06.2016 17:19
    +8

    Статья, вроде, для начинающих. Все подробно разжевывается, при этом автор вдруг вводит термины «A-запись» и «NS-сервер» и начинает на их основе что-то объяснять. В итоге все остальное для новичка выглядит полной белибердой. Ибо что это за А-запись и где B,C,D...Z-записи и зачем нужен NS сервер если уже есть DNS сервер — так и остается для читателя тайной. Гугл, конечно, никто не отменял, но очень велика вероятность, что по запросу этих терминов он выведет на более последовательные статьи для начинающих.


    1. saboteur_kiev
      17.06.2016 00:56
      -1

      Новичкам лучше рассказать про hosts файл, чтобы они не покупали себе домены, а поднимали веб сервер локально, через hosts делали виртуальные домены и там игрались.

      Если же новички захотят поднять свой DNS сервер, могут попасть под уязвимость, когда можно послать небольшой запрос, а ответ на него будет уходить целевой жертве, причем весьма большим.
      Таким образом, без всяких вирусов, без установки ботнета, просто получив список открытых (неправильно настроенных DNS серверов), можно через них быстро организовать кому-нибудь ddos.


      1. soniq
        19.06.2016 14:20
        +3

        DDOS — это, конечно, круто. Но я вот хотел уже разобраться с DNS, но на фразе

        Причина в том, что DNS производит замену таким образом, что все записи того места, куда указывает CNAME, также валидны для CNAME. В нашем примере, записи у www.petekeen.net и web01.bugsplat.info будут совпадать.
        Мой мозг завернулся в CNAME и перестал отвечать. Серьезно, я вообще не понял, о чем речь. И ведь все статьи такие: получаем адрес по имени, корневые сервера, иерахия, все понятно вроде, и тут херак, и MX запись на AAAA реестр
        O_o


  1. lockywolf
    16.06.2016 17:31

    >>Часто нужно сделать редирект домена iskettlemanstillopen.com на www.iskettlemanstillopen.com.

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

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

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


    1. zerocool56
      17.06.2016 12:24
      +2

      Логика работы DNS проста и понятна, то, как софт интерпретирует ресурсные записи, расположенные в DNS, к сложности самого протокола не имеет никакого отношения.

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

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

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

      DNSSEC — уже сложнее, но он и куда бОльший функционал несёт, хотя тоже вполне прост и понятен в большинстве случаев.


  1. HumanUser
    16.06.2016 21:04
    +1

    Вместо тысячи слов: www.amazon.com/DNS-BIND-5th-Cricket-Liu/dp/0596100574


    1. Pilat
      16.06.2016 21:53

      Есть и перевод — http://www.books.ru/books/dns-i-bind-5-e-izdanie-552030/


  1. rrrav
    16.06.2016 22:35
    +1

    Чаще всего DNS-запросы никогда не доходят до корневых серверов, потому что их IP-адреса почти никогда не изменяются.

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


    1. navion
      17.06.2016 01:46

      И ни слова про смену IP-адреса при переезде и его зависимость от коряво настроенных DNS-серверов игнорирующих TTL.


      1. grossws
        17.06.2016 02:09

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


    1. freetonik
      17.06.2016 15:13

      Тоже не совсем понял этот момент в оригинале.

      Most of the time DNS resolution will never touch the root servers because their IP addresses hardly ever change.


      Добавил ваше замечание в пост. Спасибо!


      1. rrrav
        17.06.2016 22:12

        Ага, и в оригинале тоже звучит неоднозначно — множественные формы как для корневых серверов, так и для IP адресов позволяют отнести понятие (большое TTL) как к IP адресам серверов, так и IP адресам в базе. Такой вот семантический прокол в документации — хорошо, что это не кредитный договор…


  1. xilix
    17.06.2016 00:55

    Еще больше напугал :)