Вопрос или проблема
Согласно спецификациям доменных имен RFC 1035:
2.3.4. Размерные ограничения
имена 255 октетов или меньше
Согласно SMTP RFC 5321:
4.5.3.1.2. Домен
Максимальная общая длина доменного имени или номера составляет 255 октетов.
Таким образом, RFC последовательны и ясны, на мой взгляд.
Тем не менее, некоторые люди утверждают, что это 254 из-за возможного наличия точки в конце, хотя в RFC 1 не упоминается такая точка.
Другие люди утверждают, что это 253 по странным причинам, таким как наличие байта длины префикса и завершающего ‘\0’ в строках C 2, 3, 4.
Какова максимальная длина домена в байтах?
Это зависит от контекста. Ваши RFC перечисляют разные ограничения, потому что они говорят о разных вещах – ограничение SMTP в 255 конкретно относится к доменной части local@domain
адресов электронной почты и вряд ли имеет какое-либо отношение к ограничению, установленному протоколом DNS.
(Это отчасти потому, что SMTP предшествует DNS на годы – он был разработан, когда HOSTS.TXT все еще использовался в ARPANET (см. RFC 810/811); и он существовал в мире, где электронная почта передавалась через 10 разных сетей, так что домен адреса электронной почты SMTP мог вовсе не быть доменом Интернета.)
Предварительные условия
Начнем с важной детали:
Тем не менее, некоторые люди утверждают, что это 254 из-за возможного наличия точки в конце, хотя в RFC не упоминается такая точка
Упоминается. Раздел 3.1 RFC 1034:
Когда пользователь должен ввести доменное имя, длина каждой метки опускается, а метки разделяются точками ("."). Поскольку полное имя домена заканчивается корневой меткой, это приводит к форме напечати, которая заканчивается точкой. Мы используем это свойство для различения: - строка символов, представляющая полное доменное имя (часто называемое "абсолютным"). Например, "poneria.ISI.EDU." - строка символов, представляющая начальные метки доменного имени, которое неполное, и должно быть завершено локальным программным обеспечением, используя знания о локальном домене (часто называемое "относительным"). Например, "poneria", использованное в домене ISI.EDU. Относительные имена берутся либо относительно хорошо известного происхождения, либо относительно списка доменов, используемых в качестве списка поиска. Относительные имена, как правило, встречаются в пользовательском интерфейсе, где их интерпретация варьируется от реализации к реализации, и в главных файлах, где они относительны к единому доменному имени-источнику. Наиболее распространенная интерпретация использует корень "." как либо единственный источник, либо как одного из членов списка поиска, поэтому многоэтикеточное относительное имя часто является тем, где завершающая точка была опущена для экономии времени набора.
Итак, по спецификации, www.google.com
не является полным доменным именем – www.google.com.
является – а завершающая точка просто “опущена для экономии времени набора”, но она вполне действительна и имеет конкретное назначение. Вы добавляете завершающую точку, чтобы сообщить системе, что локальный домен не должен быть добавлен.
-
В качестве практического примера, ICANN ранее позволяла доменам верхнего уровня иметь записи “хостов”. Например, TLD
tk.
имел веб-сайт по адресуhttp://tk./
– который должен был быть написан с завершающей точкой, в противном случае ваша система выполняла бы поискtk.dlink.lan
или чего-то еще. -
RFC использует пример с одной меткой, и многие предполагают, что все системы рассматривают любое много компонентное доменное имя как уже абсолютное, но это не всегда так – Windows, в частности, не ограничивает себя таким образом.
Вместо этого, если в Windows настроен суффикс поиска DNS, он будет применяться к любому не абсолютному имени, даже если у него несколько компонентов. Например, если
corp.example.com
является доменом вашей системы, тогдаwww.google.com
сначала будет опробовано какwww.google.com.corp.example.com.
и только потом какwww.google.com.
.В этой ситуации вы бы явно добавили завершающую точку к вашему вводу, чтобы предотвратить автоматическое добавление локального домена операционной системой.
Другой RFC, который вы читали – RFC 1035 – не говорит о “завершающей точке”, потому что он в основном касается сетевого протокола, в то время как детали, касающиеся пользователя, находятся в RFC 1034.
Но текстовое представление не является тем местом, откуда берется фактическое ограничение длины.
Фактические ограничения
Реальное ограничение составляет “255 октетов или меньше”, когда оно применяется к доменному имени, представленному в формате DNS сетевом (‘проводном’) формате, который не использует ‘точечные’ разделители – действительно используется байт длины префикса – и эквивалент “завершающей точки” не является обязательным.
В этом формате каждая строка предваряется байтом длины, а весь список завершается строкой, состоящей из 0 байтов. Цитируя RFC 1035:
Доменные имена в сообщениях выражаются в терминах последовательности меток. Каждая метка представлена как поле длиной один октет, за которым следует это количество октетов. Поскольку каждое доменное имя заканчивается нулевой меткой корня, доменное имя завершается байтом длины ноль. Высшие два бита каждого байта длины должны быть нулями, а оставшиеся шесть бит поля длины ограничивают метку до 63 октетов или меньше.
Например, www.google.com
станет:
14 символов: www.google.com
Интерпретируется как: [3] "www"
[6] "google"
[3] "com"
[0] "" ("нулевая метка корня")
16 байт: <0x03> w w w <0x06> g o o g l e <0x03> c o m <0x00>
(Завершающий байт 0x00 здесь не имеет никакого отношения к строкам C; в некотором смысле это полная противоположность – формат гораздо больше похож на серию строк Паскаля – но на самом деле он не связан ни с каким языком программирования. Это конкретно способ, которым доменные имена передаются в сетевом протоколе.)
Таким образом, согласно тому же RFC, ограничение для доменных имен в этой специфической форме составляет 255 байт:
Чтобы упростить реализации, общая длина доменного имени (т.е. октеты меток и октеты длины меток) ограничивается 255 октетами или меньше.
Случается, что бинарное (сетевое) представление почти всегда¹ на два байта длиннее, чем обычно используемое текстовое представление (т.е. без завершающей точки). Таким образом, если доменное имя ограничено 255 октетами в проводном формате, оно, следовательно, ограничено 253 ASCII символами в текстовом виде (плюс необязательная завершающая точка как 254-й символ).
Другими словами, все три числа верны по-своему – но они часто “утверждаются” без какого-либо контекста для их интерпретации; 255 верно для пакета формата, 254 верно для ASCII-формата с завершающей точкой (абсолютное имя), и 253 верно для “традиционного” ASCII-формата без завершающей точки.
¹ Тем не менее, есть крайний случай – литерал точка может быть записан как \.
, который представляет собой один октет в двоичном виде, но представлен как два в текстовом виде – но это крайне редко на практике; единственный раз, когда вы это увидите, будет при просмотре поля SOA “ответственного лица”, которое может иметь адрес электронной почты, написанный как fred\.foobar\.jr.example.com
.
22 символа: ab\.cd\.ef.example.com
Интерпретируется как: [8] "ab.cd.ef" (одна метка с точками!)
[7] "example"
[3] "com"
[0] "" ("нулевая метка корня")
22 байта: <x08> a b . c d . e f <x07> e x a m p l e <x03> c o m <x00>
Если вы пишете библиотеку DNS, тогда вы должны учитывать это (постоянно измеряя длину проводного формата, а не текстового формата), но в большинстве других ситуаций это безопасно игнорировать. Это когда-то было частью великого плана использовать DNS для маршрутизации отдельных почтовых ящиков (с выделенными rrtypes DNS, такими как ‘MG’ для расширения списков рассылки), который так и не был реализован, и остался лишь в значениях rname SOA.
Поскольку ваш модуль принимает доменные имена в ASCII-формате, он должен:
-
Разрешить максимум одну завершающую точку – лучше всегда добавлять или всегда убирать ее перед продолжением валидации (для последовательности).
-
Разрешить максимум 254 байта, если завершающая точка присутствует, или максимум 253 байта, если она убрана (простой метод)… или конвертировать имя в ‘проводной формат’ и затем разрешить, чтобы оно было максимум 255 байт (точный метод).
-
Слить большинство проверок “действительности доменов верхнего уровня” в обычные проверки “меток”, так как основные правила точно такие же для каждой метки, независимо от того, находится ли она первой или последней или посередине.
(Хотя существуют дополнительные правила для TLD, они не установлены протоколом – они определены политикой ICANN как поддерживателя корневой зоны, которая определяет TLD. Так что, хотя разумно иметь, например, правило “начинается с цифры” для TLD, это следует держать отдельно.)
-
Иметь режим, который ослабляет правило “разрешенные символы”. Доменные имена в общем могут содержать любые символы – только доменные имена, которые используются как имена хостов, имеют более строгие ограничения, и они исходят от того, что их “используют как имена хостов” (т.е. для поиска A/AAAA), а не от того, что они “доменные имена”.
На уровне DNS доменные имена, не являющиеся “именами хостов”, могут содержать почти все – например, они, как правило, содержат символы
_
(которые практически обязательны для записей SRV;_minecraft._tcp.example.com
– типичный пример) – поэтому, по меньшей мере, валидация доменных имен должна различать “имя хоста (без подчеркивания)” и “не имя хоста (подчеркивание допустимо)” как разные контексты.
Ответ или решение
Максимальная длина доменного имени является важным аспектом в области информационных технологий и сетевых стандартов. Согласно спецификациям, представленным в двух ключевыхRFC-документах — RFC 1035 и RFC 5321 — максимальная длина доменного имени составляет 255 октетов.
Спецификации
-
RFC 1035: Этот документ определяет протоколы и формат, используемые для передачи доменных имен через DNS. В разделе 2.3.4 говорится: "Имя не должно превышать 255 октетов". Это означает, что общее количество всех символов и разделителей не должно превышать указанного значения.
-
RFC 5321: Этот документ касается протокола SMTP, который также указывает максимальную длину доменного имени в 255 октетов. Хотя контекст немного отличается (здесь речь идет о доменах в электронной почте), предел остается одинаковым.
Различия в интерпретации максимальной длины
Существуют разные интерпретации максимальной длины доменного имени, которые могут приводить к путанице:
-
254 октета: Некоторые утверждают, что максимальная длина составляет 254 октета из-за наличия "точки" в конце доменного имени. Однако ни в одном из RFC не упоминается о необходимости учета этой точки при вычислении длины.
-
253 октета: Еще одна интерпретация ограничивает длину до 253 октетов. Это связано с тем, что в сетевом формате передается статистически больше байтов, чем просто текст. В таком формате имя делится на сегменты (или метки), каждая из которых предшествует байт с указанием длины, а в конце всегда добавляется нулевой байт.
Практическое применение
При использовании доменного имени, особенно в рамках таких систем, как DNS и электронной почты, важно учитывать эти ограничения. Например, если домен записывать в текстовом формате, максимальная длина, которую может принять пользовательская система, будет составлять 253 символа, если игнорировать точку, и 254, если она присутствует.
Рекомендации по проектированию
-
Учет длины: Разработчики должны следить за длиной доменного имени при его обработке. Рекомендуется всегда добавлять или убирать конечную точку перед дальнейшей обработкой, чтобы обеспечить согласованность.
-
Валидация: При валидации доменных имен можно использовать длину в 255 октетов для проверки, если вы работаете с сетевым (двухбайтовым) представлением, и 253 или 254 в текстовом формате, в зависимости от наличия точки в конце.
-
Различие символов: Необходимо учитывать, что доменные имена могут содержать различные символы, в том числе подчеркивания и другие специальные символы, особенно в не-хостинговых доменах.
Заключение
Таким образом, максимальная длина доменного имени составляет 255 октетов, что приняты в обеих RFC. Однако для практического применения важно учитывать контекст и формат, так как он может варьироваться в зависимости от использования. Правильное понимание и применение этих норм поможет избежать потенциальных проблем при работе с доменными именами в интернете.