DNS消息格式(RFC1035)

763 阅读12分钟

域名系统

域名系统(DNS)的管理通过区域层级结构构造,其根区域位于该层次的最顶部。根服务器是在根区域中运行的DNS服务器,这些服务器可以直接回答针对根区域内存储或缓存的记录的查询,还可以将其它请求引向相应的顶级域(TLD)服务器。

dns-root-server.png

在未缓存的DNS查询期间,每当用户在浏览器中输入网址,该操作都会触发DNS查找,并且所有DNS查找都是从根区域开始,然后沿着DNS系统的层次结构向下移动。首先到达TLD服务器,然后到达特定域服务器(可能还有子域)的服务器,直到最终到达权威域名服务器。

有13个不同的IP地址为DNS根区域提供服务,并且全球有数百个冗余根服务器来处理对根区域的请求。

一个普遍的误解是,世界上只有 13 台根服务器。实际上根服务器有许多,但只有 13 个 IP 地址用于查询不同的根服务器网络。DNS 原始架构的限制要求根区域中最多只能有 13 个服务器地址。在 Internet 面世之初,这 13 个 IP 地址的每一个都只有一台服务器,其中大多数位于美国。

如今,这13个IP地址中的每一个都有多个服务器,这些服务器使用 Anycast 路由基于负荷和距离分发请求。目前,地球上每座有人生活的大陆上都分布着600多台DNS根服务器。

每个 DNS 解析器都在其软件中内置了13个IP根服务器地址的列表。每次发起DNS查找时,递归器的第一个通信就是与这13个IP地址之一进行的。

google.com中,com是顶级域(TLD),google是二级域(SLD)。 cctv.com.cn中,cn是顶级域,com是二级域,cctv是三级域。

命名约定

<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

域名和资源记录的定义

类型(TYPE values)

TYPE主要用在资源记录中,TYPE是QTYPE的子集。

TYPE含义
A1主机IPv4地址记录,AAAA用来指定IPv6地址记录
NS2域名服务器记录,如果需要把子域名交给其它DNS服务器解析,就需要添加NS记录
CNAME5如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录,即域名的别名
SOA6SOA这种记录是所有区域性文件中的强制性记录,它必须是一个文件中的第一个记录
MX15如果需要设置邮箱,让邮箱能够收到邮件,需要添加MX记录
TXT6可以写任何东西,长度限制为255。通常用于电子邮件安全和认证实践中。

在 DNS(Domain Name System)中,不同类型的记录用于提供不同的信息。这些记录帮助将域名解析为 IP 地址,定义邮件服务器,指定权威名称服务器等。以下是一些常见的 DNS 记录类型及其用途:

1. A 记录(Address Record)

  • 用途:将域名映射到 IPv4 地址。
  • 示例:如果你要访问 example.com,A 记录会告诉你的计算机 example.com 对应的 IPv4 地址。
  • 格式: example.com. IN A 93.184.216.34 这表示 example.com 的 IPv4 地址是 93.184.216.34

2. MX 记录(Mail Exchange Record)

  • 用途:指定处理电子邮件的邮件服务器。
  • 示例:当你发送电子邮件到 user@example.com 时,MX 记录会告诉你的邮件服务器应该将邮件发送到哪个邮件服务器。
  • 格式: example.com. IN MX 10 mail.example.com. 这表示 example.com 的邮件服务器是 mail.example.com,优先级为 10。优先级越低,优先级越高。

3. NS 记录(Name Server Record)

  • 用途:指定管理特定域名的权威名称服务器。
  • 示例:当你查询 example.com 时,NS 记录会告诉你的计算机哪个服务器具有该域名的权威信息。
  • 格式: example.com. IN NS ns1.example.com. example.com. IN NS ns2.example.com. 这表示 example.com 的权威名称服务器是 ns1.example.comns2.example.com

4. CNAME 记录(Canonical Name Record)

  • 用途:将一个域名别名映射到另一个域名。它用于将一个域名指向另一个域名,而不是直接指向 IP 地址。
  • 示例:如果你有一个域名 www.example.com,你可以将其作为 example.com 的别名。
  • 格式www.example.com. IN CNAME example.com. 这表示 www.example.comexample.com 的别名,访问 www.example.com 时会自动解析到 example.com 的地址。

详细解释

A 记录

A 记录是最基本的 DNS 记录类型,用于将域名解析为 IPv4 地址。每个域名可以有多个 A 记录,以实现负载均衡或冗余。

MX 记录

MX 记录用于指定邮件服务器的优先级。如果一个域名有多个邮件服务器,优先级较低的服务器会在高优先级服务器不可用时使用。MX 记录通常与 A 记录或 AAAA 记录(IPv6 地址)结合使用。

NS 记录

NS 记录指定哪个服务器是域名的权威名称服务器。权威名称服务器负责存储域名的所有 DNS 记录,并响应对该域名的查询。

CNAME 记录

CNAME 记录用于将一个域名指向另一个域名,而不是直接指向 IP 地址。这在需要将多个子域名指向同一个主域名时非常有用。CNAME 记录不能与其他记录(如 A 记录、MX 记录)共存于同一个域名。

示例应用

  • A 记录:用户在浏览器中输入 example.com,DNS 查询返回 93.184.216.34,浏览器连接到该 IP 地址。
  • MX 记录:邮件服务器发送邮件到 user@example.com,DNS 查询返回 mail.example.com,邮件服务器连接到该邮件服务器。
  • NS 记录:DNS 查询 example.com 的 NS 记录,返回 ns1.example.comns2.example.com,这些服务器提供 example.com 的权威 DNS 信息。
  • CNAME 记录:用户在浏览器中输入 www.example.com,DNS 查询返回 example.com,然后解析 example.com 的 A 记录得到 IP 地址。

总结

DNS 记录类型各有其特定用途,理解这些记录类型及其功能对于管理和配置 DNS 至关重要。通过正确配置这些记录,可以确保域名解析顺畅,邮件发送可靠,以及服务的高可用性和冗余。

查询类型(QTYPE values)

QTYPE出现在问题字段中,QTYPE是TYPE的一个超集,所有的TYPE都是可用的QTYPE,其它QTYPE如下:

QTYPE含义
AXFR252A request for a transfer of an entire zone
MAILB253A request for mailbox-related records (MB, MG or MR)
MAILA254A request for mail agent RRs (Obsolete - see MX)
*255A request for all records

类(CLASS values)

CLASS含义
IN1the Internet
CS2the CSNET class (Obsolete - used only for examples in some obsolete RFCs)
CH3the CHAOS class
HS4Hesiod [Dyer 87]

查询类(QCLASS values)

QCLASS是CLASS的一个超集。

CLASS含义
*255any class

标准资源记录(Standard RRs)

CNAME RDATA format

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    /                     CNAME                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

CNAME: A <domain-name> which specifies the canonical or primary name for the owner. The owner name is an alias.

MX RDATA format

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                  PREFERENCE                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    /                   EXCHANGE                    /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

PREFERENCE: A 16 bit integer which specifies the preference given to this RR among others at the same owner. Lower values are preferred.

EXCHANGE: A <domain-name> which specifies a host willing to act as a mail exchange for the owner name.

其它RRs

消息格式

DNS请求和应答都是相同的消息格式,有的消息字段在不同的情况下可能为空。

    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

(顺了张图) f04e63463e8f46829e01ea9c66bd4662_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

Header段是必须存在的,它定义了消息是请求还是应答,也定义了其它段是否需要存在,以及是标准查询还是其它。

Question段描述了查询的问题,包括查询类型QTYPE,查询类QCLASS,查询的域名QNAME。 剩下3个段包含相同的格式,一系列可能为空的资源记录RRs。

Header格式

Header包含以下字段:

      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

ID: 16位标识符,用来匹配请求和应答;

QR: QR位用来指示该消息是请求消息(Query: 0)还是应答消息(Response: 1);

OPCODE: 4位字段,指定查询种类,查询种类如下:

含义
0一个标准查询QUERY,即根据域名查询IP
1反向查询IQUERY,即根据IP查询域名
2一个服务器状态请求STATUS
3-15保留

AA: Authoritative Answer,AA位在响应中有效,指出给定应答的服务器是所查域名的权威DNS;

TC: TrunCation,指示当前消息被截断,原因是长度超过了传输通道所允许的的长度;

RD: Recursion Desired,此位在请求中设置并被复制到响应中。用来指示是否以递归方式查询;

RA: Recursion Available,在响应中有效,指示服务器是否支持递归查询;

Z: 保留位,需要置零;

RCODE: Response Code,响应码,取值如下:

code含义
0no error
1格式错误
2服务器错误
3名称错误,域名不存在
4不支持
5拒绝
6-15保留

QDCOUNT: 无符号16位整数,指定quection数量;

ANCOUNT: 无符号16位整数,指定answer中RR的数量;

NSCOUNT: 无符号16位整数,指定authority records中服务器RR的数量;

ARCOUNT: 无符号16位整数,指定additional records中RR的数量;

Question格式

该部分包含QDCOUNT(通常为1)个实体,实体格式如下:

      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                     QNAME                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QTYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QCLASS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

QNAME: 域名;

QTYPE: 查询类型,2字节;

QCLASS: 查询类,2字节;

RRs格式

answer, authority和additional部分都有相同的格式:一个数量不等的资源记录(RRs),其数量在header中相应的计数字段指定。每个RR的格式如下:

      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

NAME: 一个与此资源记录有关的域名;

TYPE: 指定RR类型,2字节;

CLASS: 指定RR类,2字节;

TTL: 32位无符号整数,指定资源记录的有效期(秒)。

RDLENGTH: 16位无符号整数,指定RDATA字段的长度(字节);

RDATA: 可变字节长度字符串,格式与TYPE和CLASS有关;

消息压缩

为了减小消息,域名系统使用一种压缩方法来消除消息中域名的重复。使用这种方法,后面重复出现的域名或者labels被替换为指向之前出现位置的指针。 指针格式如下:

      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    | 1  1|                OFFSET                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

前两个比特位固定为1.因为labels限制为不多于63个字节,所以label的前两位一定为0,这样就可以让指针与label进行区分。(10和01组合保留,以便以后使用。)Offset表示消息开始的字节指针,Offset为0表示ID字段的第一个字节。

传输

DNS消息以数据报(UDP)或者虚电路上的字节流(TCP)形式来传输。TCP可用于任何DNS活动;UDP更适合用于查询,因为其开销低、性能好。但是区域刷新活动必须使用TCP以保证可靠传输。

Internet支持DNS使用端口53的TCP或UDP传输。

UDP

UDP传输的消息严格要求限制在512字节内(不包括IP和UDP头),更长会被截断,就需要设置TC位。

UDP不允许用于区域传输,推荐用于标准查询。

使用UDP发送的消息可能丢失或乱序,因此需要重传策略,并且不应依赖消息按顺序反馈。

TCP

消息以两字节的表示消息长度的字段开始,长度不包括这两个字节。底层在收取完整的报文后再交给上层处理。

dig命令

dig命令主要用来从DNS域名服务器查询主机地址信息。默认情况下dig命令查询A记录。

使用方法如下:

➜  ~ dig -h
Usage:  dig [@global-server] [domain] [q-type] [q-class] {q-opt}
            {global-d-opt} host [@local-server] {local-d-opt}
            [ host [@local-server] {local-d-opt} [...]]
Where: ...

举例:

➜  ~ dig baidu.com

; <<>> DiG 9.10.6 <<>> baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27154
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;baidu.com.			IN	A

;; ANSWER SECTION:
baidu.com.		241	IN	A	39.156.66.10
baidu.com.		241	IN	A	110.242.68.66

;; Query time: 40 msec
;; SERVER: 10.53.2.3#53(10.53.2.3)
;; WHEN: Mon Dec 26 18:15:48 CST 2022
;; MSG SIZE  rcvd: 70

dig命令默认的输出信息分为5个部分。

  • 第一部分显示dig命令的版本和输入的参数;
  • 第二部分Got answer,显示响应消息的header中的关键字段;
  • 第三部分OPT PSEUDOSECTION & QUESTION SECTION,查询的域名/QTYPE/QCLASS;
  • 第四部分ANSWER SECTION,显示响应消息的Answer部分;
  • 第五部分是本次查询的一些统计信息。

nslookup命令

nslookup命令默认查询A记录。

➜  ~ nslookup baidu.com
Server:		10.53.2.3
Address:	10.53.2.3#53

Non-authoritative answer:
Name:	baidu.com
Address: 110.242.68.66
Name:	baidu.com
Address: 39.156.66.10

指定DNS查询。

➜  ~ nslookup baidu.com 8.8.8.8
Server:		8.8.8.8
Address:	8.8.8.8#53

Non-authoritative answer:
Name:	baidu.com
Address: 39.156.66.10
Name:	baidu.com
Address: 110.242.68.66

查询NS。

➜  ~ nslookup -q=NS baidu.com
Server:		10.53.2.3
Address:	10.53.2.3#53

Non-authoritative answer:
baidu.com	nameserver = ns2.baidu.com.
baidu.com	nameserver = ns3.baidu.com.
baidu.com	nameserver = ns4.baidu.com.
baidu.com	nameserver = dns.baidu.com.
baidu.com	nameserver = ns7.baidu.com.

Authoritative answers can be found from:
ns2.baidu.com	internet address = 220.181.33.31
ns3.baidu.com	internet address = 112.80.248.64
ns3.baidu.com	internet address = 36.152.45.193
ns4.baidu.com	internet address = 14.215.178.80
ns4.baidu.com	internet address = 111.45.3.226
dns.baidu.com	internet address = 110.242.68.134
ns7.baidu.com	internet address = 180.76.76.92
ns7.baidu.com	has AAAA address 240e:bf:b801:1002:0:ff:b024:26de
ns7.baidu.com	has AAAA address 240e:940:603:4:0:ff:b01b:589a

反向查询对应的域名服务器。

➜  ~ nslookup -q=ptr 8.8.8.8
Server:		10.53.2.3
Address:	10.53.2.3#53

Non-authoritative answer:
8.8.8.8.in-addr.arpa	name = dns.google.

Authoritative answers can be found from: