Внимательный читатель найдет на этой картинке 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.
есть один адрес A
: 192.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
-серверов. Он отвечает за домен верхнего уровня info
. dig
запрашивает у одного из этих серверов запись A
для web01.bugsplat.info
, и получает в ответ еще один набор NS
-серверов, и потом запрашивает у одного из этих серверов запись A
для web01.bugsplat.info.
. И, наконец, получает ответ!
Уф! Сгенерировалось бы много трафика, но почти все эти записи были надолго закэшированы каждым сервером в цепочке. Ваш компьютер тоже кэширует эти данные, как и ваш браузер. Чаще всего DNS-запросы никогда не доходят до корневых серверов, потому что их IP-адреса почти никогда не изменяются («Наверно все таки речь идет о большом TTL для записей в их базе. Если у DNS сервера IP адрес вообще ни разу не изменялся, то это не означает, что его база навечно закеширована» — прим. от rrrav). Домены верхнего уровня com
, net
, org
, и т.д. тоже обычно сильно закэшированы.
Другие типы
Есть еще несколько типов, о которых стоит знать. Первый это 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 1034: Domain Names — Concepts and Facilities
- RFC 1035: Domain Names — Implementation and Specification
Есть еще пара интересных RFC, в том числе 4034, который описывает стандарт DNSSEC
и 5321, который описывает взаимосвязь DNS и email. Их интересно почитать для общего развития.
Комментарии (31)
istui
16.06.2016 15:50+5URL 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; ..... }
freetonik
16.06.2016 15:58Да, тут автор просто описывает типичный сценарий конкретно из Namecheap образца 2013 года :)
alsopub
16.06.2016 21:04Или можно воспользоваться публичным сервисом редиректа, прописав 174.129.25.170 (http://wwwizer.com/naked-domain-redirect).
Удобно в случае если домен привязывается к Гугл Сайтам или Гугл Блогам, где привязать можно только поддомен.
schors
16.06.2016 16:09Про CNAME более правильным примером были бы записи NS, без которых не может быть зона (домен второго уровня например). MX-то чёрт с ними.
mnasonov
16.06.2016 16:59+2Поэтому нельзя делать CNAME на корневом домене вроде petekeen.net, потому что обычно там нужны другие записи, например, MX.
Для этого продвинутые ДНС-хостеры (например zilore.com dnsimple.com) придумали ALIAS записи, которые позволяют добавить CNAME запись в корневой домен, а внутри она будет автоматически преобразована в А запись и поддерживаться в актуальном состоянии.shumaher86
16.06.2016 17:19+1есть у меня один домен, лежит в Яндекс.ПДД, однажды. еще не зная, что CNAME для самого домена прописывать нельзя, я взял и прописал, и оно почему-то сохранилось, и работает до сих пор как-то :) не знаю, может потому, что домен в .net.ru., и система восприняла его как поддомен.
позже, с другим домен хотел сделать тоже самое, а интерфейс Яндекса уже ошибку выдаёт. писал тогда по этому поводу в техподдержку, и тогда-то мне и сказали, что нельзяschors
16.06.2016 23:33Оно в среднем работать-то будет. Но шаг вправо-влево и результат непредсказуем.
shumaher86
16.06.2016 23:51тоже так подумал, поэтому больше эту запись не трогаю, наверняка сохранить уже не даст
Loki3000
16.06.2016 17:19+8Статья, вроде, для начинающих. Все подробно разжевывается, при этом автор вдруг вводит термины «A-запись» и «NS-сервер» и начинает на их основе что-то объяснять. В итоге все остальное для новичка выглядит полной белибердой. Ибо что это за А-запись и где B,C,D...Z-записи и зачем нужен NS сервер если уже есть DNS сервер — так и остается для читателя тайной. Гугл, конечно, никто не отменял, но очень велика вероятность, что по запросу этих терминов он выведет на более последовательные статьи для начинающих.
saboteur_kiev
17.06.2016 00:56-1Новичкам лучше рассказать про hosts файл, чтобы они не покупали себе домены, а поднимали веб сервер локально, через hosts делали виртуальные домены и там игрались.
Если же новички захотят поднять свой DNS сервер, могут попасть под уязвимость, когда можно послать небольшой запрос, а ответ на него будет уходить целевой жертве, причем весьма большим.
Таким образом, без всяких вирусов, без установки ботнета, просто получив список открытых (неправильно настроенных DNS серверов), можно через них быстро организовать кому-нибудь ddos.soniq
19.06.2016 14:20+3DDOS — это, конечно, круто. Но я вот хотел уже разобраться с DNS, но на фразе
Причина в том, что DNS производит замену таким образом, что все записи того места, куда указывает CNAME, также валидны для CNAME. В нашем примере, записи у www.petekeen.net и web01.bugsplat.info будут совпадать.
Мой мозг завернулся в CNAME и перестал отвечать. Серьезно, я вообще не понял, о чем речь. И ведь все статьи такие: получаем адрес по имени, корневые сервера, иерахия, все понятно вроде, и тут херак, и MX запись на AAAA реестр
O_o
lockywolf
16.06.2016 17:31>>Часто нужно сделать редирект домена iskettlemanstillopen.com на www.iskettlemanstillopen.com.
Лучше делать наоборот.
Вообще, статья не очень удачная. То есть, она неплохо называет основные термины, но создаёт ошибочную иллюзию простоты системы DNS, тогда как она на самом деле фантастически непростая.
Например, там есть инструменты для организации загрузки операционных систем по сети, также там можно хранить данные авторизации, да вообще чего только нельзя хранить.zerocool56
17.06.2016 12:24+2Логика работы DNS проста и понятна, то, как софт интерпретирует ресурсные записи, расположенные в DNS, к сложности самого протокола не имеет никакого отношения.
Ресурсных записей штук 40 всего, а часто используемых из них наберётся с десяток.
Самые ходовые А, АААА (А6), CNAME, PTR, SRV, MX, TXT.
Ну и «технические» NS, SOA
При этом софта, который использует специально оформленные TXT или SRV поля много-много больше и каждый ведёт себя по-разному (и не всегда логично).
Но сложность ли это DNS? Ничуть.
DNSSEC — уже сложнее, но он и куда бОльший функционал несёт, хотя тоже вполне прост и понятен в большинстве случаев.
HumanUser
16.06.2016 21:04+1Вместо тысячи слов: www.amazon.com/DNS-BIND-5th-Cricket-Liu/dp/0596100574
rrrav
16.06.2016 22:35+1Чаще всего DNS-запросы никогда не доходят до корневых серверов, потому что их IP-адреса почти никогда не изменяются.
Наверно все таки речь идет о большом TTL для записей в их базе. Если у DNS сервера IP адрес вообще ни разу не изменялся, то это не означает, что его база навечно закеширована.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.
Добавил ваше замечание в пост. Спасибо!rrrav
17.06.2016 22:12Ага, и в оригинале тоже звучит неоднозначно — множественные формы как для корневых серверов, так и для IP адресов позволяют отнести понятие (большое TTL) как к IP адресам серверов, так и IP адресам в базе. Такой вот семантический прокол в документации — хорошо, что это не кредитный договор…
findoff
В избраное!
Кидать «сисадминам» которые не понимают что такое CNAME и куда его прописать, а от MX вообще впадают в ступор, но на ссылку на вики почему-то обежаются.
chupasaurus
tools.ietf.org/html/rfc1034 или не пущать!
Okloks
Серьёзно? Даже такой недосисадмин как я, знает что такое MX и CNAME
findoff
Увы, но мне лично несколько раз выпадала честь проводить ликбез на пальцах, по телефону, сисадминам достаточно крупных региональных организаций. (Часто они не в курсе как работает то что настроил их предшественник)
А так же видеть некоторых дипломированных(в отличии от меня) сетевых администраторов, с большим самомнением, но имеющих проблемы даже с настройкой статической маршрутизации...
P.S.: Сам я сисадмин веб-студии, и общаюсь обычно по выкладке сайтов и о том что бы при это не отвалилась почта и прочие.
Okloks
Жесть.
Как такие люди попадают на работу? По знакомству штоле?
findoff
Я думаю что, некоторые в силу другой специфики, а админят по совместительству, тут и постыдного ничего нет. Некоторые по блату или красивым дипломам...
Судя по профилю вы старше меня и сами думаю, видели достаточно кадров...
Впрочем и сам я человек без образования, с весьма странным набором навыков, скорее дилетанта широкого профиля чем профессионала. Работаю сисадмином, dev-ops'ом, программером, по чуть чуть...