Защо коренът на домейн не може да бъде CNAME - и други неща за DNS

Този пост ще използва по-горе въпрос, за да проучи DNS, dig, Aзаписи, CNAMEзаписи и ALIAS/ANAMEзаписи от гледна точка на начинаещи. Така че нека да започнем.

Първо, някои определения

  • Система за имена на домейни (DNS): цялостната система за преобразуване на запомнящо се име на домейн (example.com) в IP адрес (93.184.216.34). IP адресът е на сървър, обикновено уеб сървър, където се съхраняват файловете, необходими за показване на уеб страница.
  • DNS сървър (известен също като сървър за имена или сървър на имена): Използва DNS софтуер за съхраняване на информация за адреси на домейни. Има няколко нива - тези, принадлежащи на всеки ISP, корен (общо 13 в целия свят), домейн от най-високо ниво (TLD, например '.com') и DNS сървъри на ниво домейн.
  • Име на домейн: домейнът (пример), комбиниран с TLD (.com). Терминът „домейн“ често се използва синонимно на името на домейна, въпреки че те са различни. Когато купувате „домейн“ от регистратор или дистрибутор, вие купувате правата върху конкретно име на домейн (example.com) и всички поддомейни, които искате да създадете (my-site.example.com, mail.example.com, и т.н.).

Поток от заявки на високо ниво

Потокът от високо ниво на това, което се случва, когато въведете „example.com“ във вашия браузър, може да бъде опростен, за да се премахнат скоковете към ISP, Root и TLD DNS сървъри, както е показано по-долу:

Един домейн обикновено има два или повече сървъра за имена, съдържащи записи, свързани с името на домейна (example.com).

Могат да се съхраняват много типове записи, повечето от които могат да имат множество записи за всеки тип:

  • A: Адресни записи, които съпоставят името на домейна с IP адрес
  • CNAME: Canonical Name Record. Използва се за псевдоним на едно име на домейн (или име на поддомейн) на друго. Ще разгледаме това по-подробно по-късно.
  • MX: Mail eXchange записи, които казват на агентите за доставка на имейли къде трябва да доставят вашия имейл
  • TXT: гъвкави текстови записи за съхраняване на низове за различни цели
  • SOA: единствен запис на начало на авторитета, съхраняван на най-високото ниво на домейна. Съдържа конкретна необходима информация за домейна, например неговия основен сървър за имена
  • NS: Сървърите на имена, свързани с домейна

Когато вашето устройство изпрати заявка, която достига до сървър за имена, сървърът търси в възела за Aзапис на домейна запис и свързания съхранен IP адрес (example.com: 93.184.216.34). След това се връща на устройството, за да се използва за изпращане на заявка до правилния уеб сървър за извличане на заявената уеб страница или ресурс.

Използване на 'dig'

dig( домейн информация groper ) е инструмент за команден ред за заявки за 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, след като са използвали a 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’