Чому корінь домену не може бути CNAME - та інші дрібниці щодо DNS

Це повідомлення буде використовувати вище питання для вивчення DNS, dig, Aзаписи, CNAMEзаписи і ALIAS/ANAMEзаписи з точки зору новачка. Тож давайте почнемо.

По-перше, деякі визначення

  • Система доменних імен (DNS): загальна система для перетворення запам'ятовуваного доменного імені людини (example.com) на IP-адресу (93.184.216.34). IP-адреса - сервера, зазвичай веб-сервера, де зберігаються файли, необхідні для відображення веб-сторінки.
  • DNS-сервер (також відомий як сервер імен або сервер імен): використовує програмне забезпечення DNS для зберігання інформації про адреси доменів. Існує кілька рівнів - ті, що належать кожному провайдеру, корінному (всього 13 у всьому світі), домені верхнього рівня (TLD, наприклад, .com) та серверах DNS на рівні домену.
  • Доменне ім’я : домен (приклад) у поєднанні з TLD (.com). Термін "домен" часто використовується як синонім доменного імені, хоча вони різні. Купуючи "домен" у реєстратора чи торговельного посередника, ви купуєте права на певне доменне ім'я (example.com) та будь-які субдомени, які ви хочете створити (my-site.example.com, mail.example.com, тощо).

Потік запитів високого рівня

Потік високого рівня того, що відбувається, коли ви вводите у веб-переглядач “example.com”, можна спростити, щоб видалити стрибки до серверів DNS провайдерів, кореневих і TLD, як показано нижче:

Домен зазвичай має два або більше серверів імен, що містять записи, що стосуються імені домену (example.com).

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

  • A: Адресні записи, які відображають доменне ім’я на IP-адресу
  • CNAME: Канонічний запис імен. Використовується для псевдоніма одного доменного імені (або імені субдомену) іншому. Ми розглянемо це більш докладно пізніше.
  • MX: Пошти eXchange, які повідомляють агентів доставки електронної пошти, куди вони повинні доставити вашу електронну пошту
  • TXT: гнучкі текстові записи для зберігання рядків для різних цілей
  • SOA: однина Запис авторизації, що зберігається на верхньому рівні домену. Містить конкретну необхідну інформацію про домен, наприклад його основний сервер імен
  • NS: Сервери імен, пов’язані з доменом

Коли пристрій надсилає запит, який надходить на сервер імен, сервер шукає у вузлі запису домену Aзапис та відповідну збережену IP-адресу (example.com: 93.184.216.34). Потім він повертається на пристрій для використання для надсилання запиту на правильний веб-сервер для отримання запитуваної веб-сторінки або ресурсу.

Використання 'dig'

dig( groper information information ) - це інструмент командного рядка для запитів серверів DNS. Ця команда зазвичай використовується для усунення несправностей або, як і зараз, щоб зрозуміти більше про налаштування системи.

$ dig example.comпризводить до тривалої відповіді, надрукованої на терміналі, вихідні дані за замовчуванням детально описані тут, з яких ми зацікавлені ANSWER SECTION.

;; ANSWER SECTION: example.com. 72703 IN A 93.184.216.34

І ось ми йдемо, ми можемо побачити, що example.comповертає Aзапис про 93.184.216.34. Іноді домени матимуть більше одного Aзапису, якщо більше ніж один веб-сервер може надати необхідну інформацію.

Є ще! Якщо спробувати деякі інші приклади, ми можемо скоро побачити , що з'являється ще одна загальна запис: CNAME.

$ dig www.skyscanner.net:

;; ANSWER SECTION: www.skyscanner.net. 169 IN CNAME www.skyscanner.net.edgekey.net. www.skyscanner.net.edgekey.net. 5639 IN CNAME e11316.a.akamaiedge.net. e11316.a.akamaiedge.net. 20 IN A 23.217.6.192
www.skyscanner.net.edgekey.net. 5639 IN CNAME e11316.a.akamaiedge.net.
e11316.a.akamaiedge.net. 20 IN A 23.217.6.192

Використання +shortпрапора дозволяє чітко бачити сформований шлях:

$ dig www.skyscanner.net +short

www.skyscanner.net.edgekey.net. e11316.a.akamaiedge.net. 23.217.6.192

CNAME

CNAMEЗапис дозволяє доменне ім'я , яке буде використовуватися в якості псевдоніма для іншої канонічної (істинної) області.

Коли DNS-сервер повертає CNAMEзапис, він не повертає його клієнту. Швидше він знову шукатиме повернене доменне ім’я та, у свою чергу, поверне AIP-адресу запису. Цей ланцюжок може тривати багато CNAMEрівнів углиб, але потім зазнає незначних показників продуктивності від кількох пошуків перед кешуванням.

Простим прикладом цього може бути, якщо у вас є сервер, на якому ви зберігаєте всі свої фотографії. Як правило, ви можете отримати до нього доступ photos.example.com. Однак, можливо, ви також хочете, щоб він дозволив доступ через photographs.example.com. Один з способів зробити це можливим , щоб додати CNAMEзапис , яка вказує photographsна photos. Це означає, що коли хтось відвідує, photographs.example.comйому буде надано такий самий вміст, як photos.example.com.

За допомогою запиту $ dig photographs.example.comми побачили б:

photographs.example.com IN CNAME photos.example.com photos.example.com IN A xx.xxx.x.xxx

Важливо зазначити, що CNAMEце той шматок праворуч. Ліва сторона - це псевдонім або мітка.

Іншим поширеним використанням є wwwсубдомен. Придбавши, example.comви також хочете, щоб користувачі, які вводять текст, www.example.comбачили той самий вміст.

Тут варто зауважити, що example.comїх можна назвати вершиною, кореневим чи відкритим доменним іменем.

Одним із варіантів було б встановити інший Aзапис із вказівкою на ту саму IP-адресу, що і для example.com. Це цілком справедливо, і це те, що example.comробить справжній , але це не дуже добре. Що станеться, якщо вам потрібно оновити IP-адресу, на яку example.comвказує? Вам також потрібно буде оновити його для wwwсубдомену та інших, які ви можете використовувати.

Якщо CNAMEзапис використовувався для псевдоніма, www.example.comщоб вказувати на нього, example.comтоді потрібно було б оновити лише кореневий домен, оскільки всі інші вузли вказують на нього.

Обмеження CNAME

На момент написання стандартів DNS було встановлено деякі правила, що регулюють їх використання. RFC 1912 та RFC 2181 встановлюють, що:

  • SOAа NSзаписи обов’язково повинні бути присутніми в кореневому домені
  • CNAMEзаписи можуть існувати тільки в вигляді окремих записів і не можуть бути об'єднані з будь-якої іншої записом ресурсу (DNSSEC SIG, NXTі KEY RRзаписами звільнені)

Це виключає CNAMEвикористання в кореневому домені, оскільки ці два правила суперечать одне одному.

Тут важливо те, що це контрактне обмеження, а не технічне. Можна використовувати a CNAMEв корені, але це може призвести до несподіваних помилок, оскільки це порушує очікуваний контракт поведінки.

Приклад цього розповідає Cloudflare, описуючи проблеми, з якими вони зіткнулися з поштовими серверами Microsoft Exchange після використання в CNAMEкореневому домені:

Домени зазвичай позначають сервери, які обробляють їх електронну пошту через так званий MX Record. Проблема полягала в тому, що сервери Exchange… могли взяти CNAME у кореневому записі, а потім неправильно поважати CNAME, встановлений у записі MX. Ви насправді не можете звинуватити Exchange. Вони працювали за припущеннями, викладеними в специфікації DNS.

Here you see the downside that can appear in several server softwares or libraries. Because a standard is in place for a CNAME to be the only record at a node, no other records are looked for. All other records will be silently ignored, without warning or error messages. Even if an MX record was set to receive email, the MX will be ignored as if it doesn’t exist because the CNAME is evaluated first. The same is true if there were an A record: the CNAME would take precedence and the A record would not be read.

The modern internet

So why is this a problem? Why would you ever want to use a CNAME for your root domain anyway? Surely that is the end of the path when looking for the IP address of the web server hosting your content?

In the modern internet landscape, that is no longer the case. The world is very different from when the DNS standards were written.

You may choose to use a Platform as a Service (PaaS) provider like Heroku and store content on their web servers. You control the content, but not the infrastructure, and the PaaS provider does the heavy lifting of the network maintenance. They typically provide you with a URL (my-app.herokuapp.com) that is a subdomain of their root domain, and you can view the IP addresses for the web server(s) your content is on. But these are entirely under the PaaS provider’s control, and will change without warning.

The scale and frequency of backend changes made by the PaaS provider can make it hard to maintain your root domain A record pointing at a single IP address. Ideally you would wish to do this:

example.com IN CNAME my-app.herokuapp.com.www.example.com IN CNAME my-app.herokuapp.com.example.com IN CNAME my-app.herokuapp.com. www.example.com IN CNAME my-app.herokuapp.com.

to allow Heroku (or your chosen host provider) to manage updating the A record that the CNAME points to without any changes made on your side. However, as we now know, this breaks the DNS specification, so is a very bad idea.

It is possible to simply implement a 301/302 redirect from example.com to www.example.com. However, that instruction takes place either on the web server (so still having the problem of needing to use a fixed A record in DNS to point to that web server), or a custom DNS provider redirect (that suffers complications with HTTPS).

This also has the side effect of changing the domain that you see in the URL bar, which you may not want. This method is intended for when your website has permanently moved, or when you’re trying to preserve SEO rankings, rather than solving our problem of pointing to a complex changing backend in a scaleable way.

The solution

Several DNS providers have now developed custom solutions to work around this problem, including:

  • ALIAS at DNSimple
  • ANAME at DNS Made Easy
  • ANAME at easyDNS
  • CNAME (virtual) at CloudFlare

These are all virtual record types that provide CNAME like behaviour, with none of the downsides. The exact implementation can differ, but at a high level when the DNS server sees one of these virtual record types, it acts as a DNS resolver. It follows the chain created by the alias until it resolves at an A record (or records) and returns these A records to the DNS server. This ‘flattens’ the CNAME chain into the A record(s) returned, and is indistinguishable to the sent query. The query sees only a pure A record, which doesn’t break the DNS specification, and doesn’t have any of the disadvantages of a CNAME.

These virtual records can sit alongside other records at the root without any fear of unintended behaviours. Depending on the provider’s method of DNS resolution when following the CNAME chain, they may also have performance benefits from caching previous lookups.

For a DNSimple setup, we would then configure as below. This solution has all the advantages of domain name aliasing, and none of the risks of using it at root level.

example.com IN ALIAS my-app.herokuapp.com.www.example.com IN CNAME my-app.herokuapp.com.

Thanks for reading! ?

As always, open to any corrections or additional points.

Resources

  • What is a DNS Server
  • Set Up a DNS Name Server
  • DNSimple support pages and ALIAS blog
  • Cloudflare support and CNAME blog
  • dig HowTo
  • Several great Stack Overflow or StackExchange posts
  • Well written Wikipedia entries
  • Netlify blog ‘To www or not www’