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

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.
є одна адреса
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 ms 15

Інформація виводиться в ієрархічній послідовності. Пам'ятайте
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, в тому числі 4034, який описує стандарт
DNSSEC
та 5321, який описує взаємозв'язок DNS і email. Їх цікаво почитати для загального розвитку.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.