May 1, 2018 · DNS 本文字数: 1.5k 阅读时长:7 min 全站字数:361.8k

RFC文档中对DNS域名格式的说明

  1. 1 RFC文档中关于域名的规范
  2. 2 关于域名的限制及限制的原因
    1. 2.1 域名长度限制说明

1 RFC文档中关于域名的规范

1
2
3
4
5
6
Domain names in messages are expressed in terms of a sequence of labels.
Each label is represented as a one octet length field followed by that
number of octets. The domain name terminates with the
zero length octet for the null label of the root. Note
that this field may be an odd number of octets; no
padding is used.

在[RFC1035(https://tools.ietf.org/html/rfc1035#section-2.3.1)中推荐的域名语法为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
The following syntax will result in fewer problems with many applications that use domain names (e.g., mail, TELNET).

<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
<letter> ::= any one of the 52 alphabetic characters A through Z in
upper case and a through z in lower case
<digit> ::= any one of the ten digits 0 through 9

Note that while upper and lower case letters are allowed in domain
names, no significance is attached to the case. That is, two names with
the same spelling but different case are to be treated as if identical.

The labels must follow the rules for ARPANET host names. They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen. There are also some
restrictions on the length. Labels must be 63 characters or less.

在RFC1035规范中,要求域名要遵循ARPANET的主机名格式,即必须以字母开头,以字母或者数字结尾,中间部分为字母,数字和连字符。长度必须是63个字符或者更短。

域名不区分大小写,但是需要尽量保留大小写,除非不可能,如在数据库中存储。

RFC2181中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Occasionally it is assumed that the Domain Name System serves only
the purpose of mapping Internet host names to data, and mapping
Internet addresses to host names. This is not correct, the DNS is a
general (if somewhat limited) hierarchical database, and can store
almost any kind of data, for almost any purpose.

The DNS itself places only one restriction on the particular labels
that can be used to identify resource records. That one restriction
relates to the length of the label and the full name. The length of
any one label is limited to between 1 and 63 octets. A full domain
name is limited to 255 octets (including the separators). The zero
length full name is defined as representing the root of the DNS tree,
and is typically written and displayed as ".". Those restrictions
aside, any binary string whatever can be used as the label of any
resource record. Similarly, any binary string can serve as the value
of any record that includes a domain name as some or all of its value
(SOA, NS, MX, PTR, CNAME, and any others that may be added).
Implementations of the DNS protocols must not place any restrictions
on the labels that can be used. In particular, DNS servers must not
refuse to serve a zone because it contains labels that might not be
acceptable to some DNS client programs. A DNS server may be
configurable to issue warnings when loading, or even to refuse to
load, a primary zone containing labels that might be considered
questionable, however this should not happen by default.

Note however, that the various applications that make use of DNS data
can have restrictions imposed on what particular values are
acceptable in their environment. For example, that any binary label
can have an MX record does not imply that any binary name can be used
as the host part of an e-mail address. Clients of the DNS can impose
whatever restrictions are appropriate to their circumstances on the
values they use as keys for DNS lookup requests, and on the values
returned by the DNS. If the client has such restrictions, it is
solely responsible for validating the data from the DNS to ensure
that it conforms before it makes any use of that data.

DNS不仅仅是一个用于将域名映射为数据,将地址映射为主机名。DNS是一个通用
的层次性数据库,可以存储所有类型的数据,用于任何目的。

关于DNS域名的限制是:标签用于区分资源记录集,每个标签的长度是1-63个字节。完整的域名最长255字节,包括分隔符(点)。0个长度的域名是DNS域名树的根,通常展示为.。除此之外,任意的二进制字符串都是允许的。这个也应该是私有托管域允许支持的域名类型。

特殊的应用和场景可以对DNS有限制,但不是默认的。

RFC4343中,重新明确了域名中大小写的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Case Insensitivity of DNS Labels

DNS was specified in the era of [ASCII]. DNS names were expected to
look like most host names or Internet email address right halves (the
part after the at-sign, "@") or to be numeric, as in the in-addr.arpa
part of the DNS name space. For example,

foo.example.net.
aol.com.
www.gnu.ai.mit.edu.
or 69.2.0.192.in-addr.arpa.

Case-varied alternatives to the above [RFC3092] would be DNS names
like

Foo.ExamplE.net.
AOL.COM.
WWW.gnu.AI.mit.EDU.
or 69.2.0.192.in-ADDR.ARPA.

However, the individual octets of which DNS names consist are not
limited to valid ASCII character codes. They are 8-bit bytes, and
all values are allowed. Many applications, however, interpret them
as ASCII characters.

2 关于域名的限制及限制的原因

1
2
labels          63 octets or less
names 255 octets or less

标签的长度被限制为63,是为了在DNS协议中支持域名压缩,及对相同域名使用指针。在DNS协议的数据中指针前两位是两个bit的1。由于域名中标签的长度最大为63,所以表示长度的字节的前两位是0。这样域名的压缩和正常的存储就不会冲突。

至于域名最大长度为什么是255个字节,RFC中说是为了实现简单,域名长度限制为255个字节或者更少。

2.1 域名长度限制说明

域名的外部表示是一个字节的标签值,一个字节点字符。内部表示是一个字节的长度加一个字节的标签的值。

域名的外部展示形式不能超过254个字节(字符)。如果是253,那么内部的255字节存储不下:一个字节表示标签长度,剩下的253个字节为标签的值,结尾的一个字节值为0表示根域,总长度正好等于255个字节。当然如果域名以点结束,如www.163.com.,则域名的外部表示的总长度可以为254。外部表示中标签长度范围是0到63,所以最多有127个标签。127个长度为1的标签值加126个点,共253。

下面是域名外部和内部表示的示例:

1
2
3
4
5
6
7
外部表示:s2.symcb.com

内部表示:
02 73 32 --> s2
05 73 79 6d 63 62 --> symcb
03 63 6f 6d --> com
00 --> . (root)