Давайте уже разберемся в DNS
Люди часто озадачены доменами. Почему мой сайт не работает? Почему эта хрень поломана, ничего не помогает, я просто хочу, чтобы это работало! Обычно, вопрошающий или не знает про 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-адреса почти никогда не изменяются. Домены верхнего уровня 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. Их интересно почитать для общего развития.
Комментарии
Комментарий удален модератором
Комментарий удален модератором
Вапщето это материал для сисадминов. А у мну в сообе они водятся.
Тут всякий народ, и материалы разные, для всех, попроще и сложные.
Комментарий удален модератором
Вы, в своём деле/профессии разбираетесь. Извините, если чё непонятное для Вас. Буду почаще приносить для новичков.
К примеру, вы умеете водить машину, а я не умею. Значит, я чайник или дура, если на дорогу выеду.))) Не умею, и учиться не хочу. Быстрей на лошади доскачу.)))
Этот материал, действительно для админов или пентестеров предназначен.
А Вы не стесняйтесь меня спрашивать, в личку. А можно и в статьях. Насмешников, кто больше знает, найду как одёрнуть и напомнить им, как сами начинали учиться.
Комментарий удален модератором
Комментарий удален модератором
Всё было интересно. И админ классный, хоть и моложе меня. Вот так получилось, из охраны в помощники сисадмина. Да щас расскажу. В этом же сообе.
Комментарий удален модератором
Это не значит, шо Рибу, хуже питона. Просто не получается с ними работать. Но я учусь. Вот и не нравятся пока проги на них написанные.