Что такое запись CNAME
Запись CNAME (canonical name record) говорит, что одно имя DNS — алиас другого. www.example.com CNAME example.net означает: всё, что вы хотите узнать о www.example.com, спрашивайте у example.net. Имя слева — это алиас; имя справа — каноническое имя, оно же цель.
CNAME хранит имя хоста, а не IP-адрес. Она не говорит, где живёт сайт — она говорит, какое другое имя это знает. В этом весь смысл: владелец цели может менять её адреса в любой момент, и каждый алиас, указывающий на неё, следует за изменением без того, чтобы кто-то редактировал свою собственную зону.
У записи те же четыре части, что и у любой другой записи DNS: имя, TTL, тип и значение. В файле зоны она выглядит, как в примере ниже. Обратите внимание на точку после цели — она отмечает имя как полное; к этой детали мы вернёмся в разделе про ошибки.
CNAME встречаются повсюду, если начать их искать. www, указывающий на хост CDN, shop.example.com, указывающий на платформу хостингового магазина, status.example.com, указывающий на сервис статус-страницы, и записи верификации, которые просят создать SaaS-инструменты, очень часто тоже CNAME. Руководство по DNS описывает другие типы записей; это руководство остаётся на алиасе.
Записи CNAME в файле зоны
$ORIGIN example.com.
; name TTL class type target (canonical name)
www 3600 IN CNAME example.cdn-provider.net.
shop 3600 IN CNAME shops.hosted-store.example.
status 3600 IN CNAME example.status-service.example.
Как резолвер следует по CNAME
Браузеры никогда не запрашивают CNAME напрямую. Они запрашивают адрес: запись A для IPv4 и AAAA для IPv6. CNAME вступает в игру, когда резолвер, выполняющий поиск за них, находит её на пути.
Резолвер спрашивает у авторитетных серверов имён example.com запись A для www.example.com. Вместо адреса ему отвечают CNAME: www.example.com — алиас example.cdn-provider.net. Резолвер начинает поиск заново для имени цели, на этот раз у серверов имён cdn-provider.net, и получает там запись A. Браузеру возвращаются обе записи: сначала CNAME, затем адрес.
Когда один и тот же сервер имён авторитетен для обоих имён, он помещает всю цепочку в один ответ и экономит второй запрос. В остальных случаях каждый переход — отдельный поиск, из-за чего CNAME может стоить несколько миллисекунд при холодном кэше и ничего не стоить, когда ответы уже закэшированы.
Если вы запрашиваете именно тип CNAME, резолвер останавливается на алиасе и не идёт дальше. Именно это делает CNAME lookup в большинстве онлайн-инструментов: он показывает, на какое имя указывает алиас, а не адрес, к которому он в итоге приводит.
$ dig www.example.com A +noall +answer
www.example.com. 3600 IN CNAME example.cdn-provider.net.
example.cdn-provider.net. 60 IN A 203.0.113.25
$ dig www.example.com CNAME +short
example.cdn-provider.net.
CNAME против записей A и AAAA
Запись A сопоставляет имя с адресом IPv4, а AAAA — с адресом IPv6. Это конец любого поиска: какую бы цепочку алиасов ни прошёл резолвер, он останавливается на записи A или AAAA. CNAME сопоставляет имя другому имени и всегда требует ещё один шаг.
Используйте A или AAAA, когда вы сами контролируете адрес и он редко меняется: собственный сервер, балансировщик с фиксированным IP, VPS. Вы поддерживаете адрес сами, и если он изменится, придётся редактировать каждую запись, где он указан.
Используйте CNAME, когда адресом управляет кто-то другой: CDN, хостинговая платформа, SaaS-инструмент. Их адреса могут меняться, различаться по регионам или браться из пула, и вам не обязательно это знать. CDN в частности может отвечать на одно и то же имя разными адресами edge-узлов в разных местах; CNAME на его имя получает это поведение бесплатно, а скопированный IP-адрес замораживает один ответ.
Практическая разница в скорости невелика. CNAME добавляет поиск только тогда, когда цель не закэширована, а популярные цели почти всегда закэшированы. Разница в обслуживании велика: жёстко прописанная запись A на IP провайдера — классическая причина того, что сайт перестаёт работать через месяцы, когда провайдер меняет нумерацию.
Почему корневой домен не может быть CNAME
Правило идёт из исходной спецификации DNS. RFC 1034, раздел 3.6.2, говорит, что если при имени присутствует CNAME, там не должно быть никаких других данных, а RFC 2181 это подтверждает. Причина — в том, как работает резолюция: CNAME означает «всё об этом имени находится в другом месте», поэтому резолвер, обнаружив её, прекращает искать что-либо ещё при этом имени. Вторая запись рядом была бы либо проигнорирована, либо противоречила бы первой. Единственное исключение — записи DNSSEC, подписывающие саму CNAME.
У корневого домена (apex, «голый» example.com) всегда есть другие записи. У каждой зоны на apex обязательно должны быть запись SOA и записи NS, а у большинства доменов там же есть и записи MX для почты, и TXT для SPF и верификации домена. CNAME на apex пришлось бы заменить их все, поэтому стандарт её запрещает, и большинство провайдеров DNS откажутся её сохранить.
Провайдеры, которые всё же её принимают, получают зону, которая ломается непредсказуемо: одни резолверы возвращают CNAME и теряют записи MX, из-за чего почта начинает возвращаться; другие возвращают записи MX и игнорируют алиас. Именно поэтому www — классическое место для CNAME, а «голый» домен требует другого решения, о котором следующий раздел.
Почему на apex уже есть записи, с которыми CNAME столкнётся
example.com. 3600 IN SOA ns1.dns-host.example. hostmaster.example.com. ( ... )
example.com. 3600 IN NS ns1.dns-host.example.
example.com. 3600 IN MX 10 mail.example.com.
example.com. 3600 IN TXT "v=spf1 include:_spf.mail.example ~all"
; example.com. 3600 IN CNAME example.cdn-provider.net. <- not allowed here
www.example.com. 3600 IN CNAME example.cdn-provider.net. ; fine: www has no other records
ALIAS, ANAME и CNAME flattening
Поскольку людям хочется поставить на CDN и «голый» домен, провайдеры DNS придумали обходные пути. Они называются по-разному, но делают одно и то же: провайдер сам следует по алиасу за вас и публикует результат как обычные записи A и AAAA на apex.
Вы настраиваете нечто похожее на CNAME на example.com. Когда приходит запрос, сервер имён провайдера сам разрешает цель, берёт найденные адреса и отвечает ими. Для внешнего мира на apex — обычные записи A и AAAA, поэтому рядом с ними законно могут стоять SOA, NS, MX и TXT. Одни провайдеры называют это записью ALIAS, другие — ANAME, третьи — CNAME flattening. У Amazon Route 53 свои записи alias, которые указывают только на ресурсы AWS. ANAME предлагали как стандарт, но так и не довели до конца, так что всё это — функция конкретного провайдера, а не тип записи, который переезжает с вами между провайдерами.
Стоит знать и о компромиссах. Адреса выбираются исходя из того, где находится сервер имён провайдера, а не где находится посетитель, поэтому CDN, отвечающий по-разному в зависимости от региона, может выдать менее подходящий edge-узел — если провайдер не передаёт сеть посетителя дальше (EDNS Client Subnet). Провайдер также сам решает, как часто обновлять ответ, и это может отставать от TTL цели. А при переезде на другой DNS-хостинг эта функция не переедет с вами.
Есть и более новый стандартный ответ: у типа записи HTTPS (RFC 9460) есть форма алиаса, разрешённая на apex. Поддержка этой формы в браузерах пока ограничена, так что считайте это решением на будущее, а не сегодняшним исправлением.
Чего CNAME не делает
CNAME — это не редирект. Она меняет только то, на какие адреса разрешается имя, и ничего больше. В адресной строке по-прежнему www.example.com, браузер всё так же отправляет Host: www.example.com в каждом запросе и запрашивает при TLS-хендшейке сертификат, действительный для www.example.com.
Отсюда два следствия, на которых спотыкаются чаще всего. Во-первых, сервер за целью должен быть настроен принимать ваше имя хоста. Направление www на somebody-else.example.net через CNAME не заставляет чужой сервер отдавать ваш сайт — он отдаёт то, что отдаёт для неизвестного Host, часто страницу ошибки или сайт по умолчанию. Именно поэтому CDN и хостинговые платформы просят сначала добавить имя хоста в своей панели, а DNS направить вторым шагом.
Во-вторых, сертификат должен покрывать ваше имя, а не имя цели. Сертификат для example.cdn-provider.net не поможет посетителю www.example.com; без сертификата для вашего собственного имени браузеры покажут предупреждение о сертификате, даже если DNS настроен правильно.
Если вам нужно, чтобы посетители переходили с одного URL на другой с изменением адресной строки, — это HTTP-редирект, 301 или 302, который отдаёт веб-сервер. См. 301 против 302.
Частые ошибки с CNAME
CNAME на apex. Разобрано выше: используйте варианты для корневого домена, которые предлагает ваш DNS-хостинг, вместо того чтобы силой ставить CNAME на example.com.
CNAME рядом с другими записями. Правило действует для любого имени, не только для apex. Если www нужна запись TXT для верификации, или у shop уже есть запись MX, вы не можете добавить туда же CNAME. Большинство провайдеров откажут; те, что не откажут, оставят вам имя, которое отвечает по-разному у разных резолверов. Размещайте записи верификации на отдельном имени, если сервис это позволяет.
Пропущенная точка на конце. В файле зоны имя без точки на конце — относительное, и к нему добавляется имя зоны. www CNAME example.cdn-provider.net внутри example.com превращается в example.cdn-provider.net.example.com. — имя, которого не существует. Пишите цель с точкой на конце. Веб-редакторы DNS различаются: большинство принимают цель без точки и добавляют её сами, некоторым точка нужна. Проверяйте результат с dig, а не доверяйте форме.
CNAME на IP-адрес. Значением CNAME должно быть имя хоста. www CNAME 203.0.113.25 либо будет отклонена, либо сохранена как имя, которое никогда не резолвится. Адресу место в записи A или AAAA.
Длинные цепочки. CNAME может указывать на другую CNAME, но каждый переход — это ещё один возможный поиск и ещё один TTL. Резолверы сдаются после фиксированного числа переходов, а цикл (a на b, b обратно на a) падает сразу. Указывайте прямо на конечное имя, которое дал вам провайдер.
MX или NS, указывающие на алиас. RFC 2181, раздел 10.3, говорит, что цели записей MX и NS должны иметь собственные адреса, а не быть CNAME. Некоторые почтовые серверы всё же доставляют письма, другие — нет.
Висящие CNAME. Когда вы отключаете сервис, но оставляете promo.example.com CNAME old-campaign.platform.example, любой, кто позже заявит это имя на той же платформе, может отдавать контент на вашем поддомене. Это захват поддомена (subdomain takeover). Удаляйте CNAME вместе с сервисом.
Точка на конце: правильно и неправильно (файл зоны для example.com)
; wrong: relative target, becomes example.cdn-provider.net.example.com.
www 3600 IN CNAME example.cdn-provider.net
; right: fully qualified target
www 3600 IN CNAME example.cdn-provider.net.
; wrong: a CNAME plus another record at the same name
shop 3600 IN CNAME shops.hosted-store.example.
shop 3600 IN MX 10 mail.example.com.
Как посмотреть запись CNAME
dig (Linux, macOS, Windows через WSL) — самый наглядный инструмент. dig www.example.com CNAME +short печатает цель алиаса. dig www.example.com +noall +answer печатает всю цепочку до адресов. dig @1.1.1.1 ... или dig @8.8.8.8 ... спрашивает конкретный публичный резолвер, что помогает, если вы подозреваете закэшированный ответ. А dig +trace проходит делегирование от корневых серверов вниз, показывая, что говорят авторитетные серверы имён прямо сейчас, минуя любой кэш.
nslookup есть везде, включая обычный Windows: nslookup -type=CNAME www.example.com. В Windows PowerShell команда Resolve-DnsName www.example.com -Type CNAME даёт более аккуратный ответ.
Онлайн-инструменты проверки отвечают со своих собственных резолверов, часто сразу из нескольких стран. Они полезны для одного конкретного вопроса: видит ли остальной мир тот же ответ, что и вы? Если в одних местах показывается старая цель, а в других — новая, изменение ещё распространяется.
Если ответ выглядит неправильно, спросите напрямую авторитетный сервер имён. Сначала найдите его с dig NS example.com +short, затем опросите его с помощью @. Если у авторитетного сервера правильный ответ, а у публичного резолвера нет, вы смотрите на кэш, который ещё не истёк. Если авторитетный сервер отвечает неправильно, нужно исправлять саму запись — там, куда указывают записи NS.
# the target of the alias
dig www.example.com CNAME +short
# the full chain, alias to address, from a public resolver
dig @1.1.1.1 www.example.com +noall +answer
# straight from the authoritative nameserver, no cache involved
dig NS example.com +short
dig @ns1.dns-host.example www.example.com CNAME +short
# Windows
nslookup -type=CNAME www.example.com
Resolve-DnsName www.example.com -Type CNAME
TTL и распространение изменений для CNAME
Каждая запись в цепочке кэшируется на собственный TTL. В примере с dig выше у CNAME TTL 3600 секунд, а у записи A цели — 60 секунд. Резолвер держит алиас час, а адрес — минуту. Именно такое разделение нужно при работе с CDN: провайдер может переместить свои адреса в течение минуты, пока ваша собственная запись почти никогда не меняется.
Оно же показывает, сколько времени занимают ваши собственные изменения. Если вы перенаправите www с одной цели на другую, резолверы, закэшировавшие старую CNAME, продолжат её использовать, пока не истечёт её TTL, так что при TTL 3600 переключение завершится в течение часа после сохранения. Снизьте TTL до 300 за день до планового изменения, внесите изменение, затем поднимите его обратно.
Две вещи занимают больше времени, чем TTL самой записи. Имя, которого раньше не существовало, может быть закэшировано как «не существует» на время негативного кэширования из записи SOA зоны; добавление CNAME сразу после того, как кто-то его искал, может показаться не сразу именно по этой причине. И смена серверов имён у вашего регистратора — это другая операция, не смена записи: она зависит от TTL, который даёт делегированию реестр, а это часто день-два. Руководство по DNS рассказывает о распространении изменений в целом.
Направление домена на CDN через CNAME, на CDN.com.tr
Типичная настройка CDN размещает www и другие поддомены на CNAME, указывающей на имя хоста CDN, а корневой домен обрабатывает отдельно. На CDN.com.tr в панели можно выбрать один из трёх способов доставки.
Default Endpoint отдаёт ваш контент с имени хоста вида xyz.cdn.com.tr без какой-либо работы с DNS. Это самый быстрый способ протестировать сервис, а позже можно перейти на собственный домен.
Custom Domain/Subdomain (CNAME) оставляет ваш DNS там, где он есть. Вы добавляете имя хоста в панели, например www.example.com или assets.example.com, и создаёте на своём DNS-хостинге CNAME, указывающую на цель, которую показывает панель, в виде <yourname>.cdn.com.tr. Скопируйте цель точно, без лишних префиксов. Корневой домен этим способом использовать нельзя; для него панель предлагает A-запись или полный перенос DNS. Имя хоста, подключённое через CNAME, получает собственный сертификат, проверяемый по HTTP, как только запросы доходят до edge. Поскольку имена хостов CDN несут записи AAAA рядом с записями A, CNAME на нас также даёт имени IPv6 без дополнительной записи с вашей стороны.
Full DNS Transfer (полный перенос DNS) переносит серверы имён домена на CDN.com.tr. Это чистое решение проблемы apex: панель становится редактором вашей зоны, корневой домен маршрутизируется на edge без обходного пути с CNAME, а корень получает wildcard-сертификат, покрывающий его поддомены. Панель сканирует и импортирует ваши существующие записи (MX, TXT, поддомены) перед переключением серверов имён, и сертификат можно выпустить через TXT-запись DNS у текущего провайдера ещё до переключения, чтобы HTTPS работал с первой минуты.
Руководство по настройке DNS для CDN разбирает переключение шаг за шагом. После того как CNAME начнёт резолвиться, проверьте, что запросы действительно идут через edge: заголовок ответа X-Proxy-Cache-MT показывает, отдал ли edge ответ из своего кэша.
$ dig www.example.com CNAME +short
yourname.cdn.com.tr.
$ curl -sI https://www.example.com/ | grep -i x-proxy-cache-mt
X-Proxy-Cache-MT: HIT
Частые вопросы о CNAME
Можно ли использовать CNAME для моего корневого домена?
По стандартным правилам DNS — нет. CNAME должна быть единственной записью при своём имени, а у корневого домена всегда есть записи SOA и NS, обычно ещё MX и TXT. Используйте записи A и AAAA, функцию ALIAS, ANAME или flattening вашего DNS-провайдера, либо перенесите DNS к провайдеру, обслуживающему сайт, чтобы он мог отвечать на apex напрямую.
CNAME — это то же самое, что редирект?
Нет. CNAME меняет только то, на какие адреса резолвится имя; браузер сохраняет ваше имя хоста в адресной строке, в заголовке Host и при проверке сертификата. Редирект — это HTTP-ответ вроде 301, который отправляет посетителя на другой URL.
Может ли CNAME указывать на другой домен?
Да, это её самое распространённое применение: www.example.com, указывающий на хост CDN или SaaS в чужом домене. Цель должна быть просто резолвящимся именем хоста. Сервис за ней также должен быть настроен принимать ваше имя хоста и иметь для него сертификат.
Можно ли иметь CNAME и MX или TXT на одном имени?
Нет. При имени с CNAME не может быть никаких других записей, кроме подписей DNSSEC. Если сервису нужны и TXT, и CNAME на одном имени, разместите TXT на другом имени, если сервис это позволяет, либо используйте вместо CNAME запись A.
CNAME медленнее записи A?
Только при холодном кэше, когда резолверу нужно отдельно искать цель; это стоит нескольких миллисекунд. Закэшированные ответы ничего не стоят дополнительно. Гибкость обычно стоит намного больше этой разницы, особенно когда цель принадлежит CDN, который меняет свои адреса.
Сколько времени занимает изменение CNAME?
До истечения TTL старой записи: резолверы хранят предыдущий ответ, пока он не истечёт. При TTL 3600 секунд это максимум час. Совсем новое имя может занять больше времени, если его недавно искали и закэшировали как несуществующее. Снижайте TTL за день до планового изменения.
В чём разница между CNAME и DNAME?
CNAME делает алиасом одно конкретное имя. DNAME делает алиасом целое поддерево: каждое имя под old.example.com сопоставляется тому же имени под new.example.net, но не само old.example.com. DNAME редко встречается на сайтах, и многие DNS-хостинги её не предлагают.