DNS 协议解析
1. 什么是 DNS
DNS(Domain Name System)是一个分布式的数据库,用于域名和 IP 地址之间的映射。这是一个应用层协议,用于将域名解析为 IP 地址。简单来说就是将域名解析为 IP 地址。
2. DNS 协议
DNS 协议的主要部分就是 DNS 的报文。RFC 1035 定义了 DNS 协议的报文格式。DNS 只有一个报文格式,被用于所有的查询和响应。DNS 报文格式如下:
1 | |
2.1 Header
Header 格式如下
1 | |
其中:
- ID: 16 位标识符,用于查询和响应的匹配,查询和响应的 ID 相同。(服务器、客户端都使用)
- QR: 1 位,查询/响应标志,0 为查询,1 为响应。(服务器、客户端都使用)
- Opcode: 4 位,操作码,0 为标准查询,1 为反向查询,2 为服务器状态请求。(客户端使用)
- AA: 1 位,授权回答标志,1 为授权回答。(服务器使用)
- TC: 1 位,截断标志,1 为报文被截断。(服务器、客户端使用)
- RD: 1 位,期望递归标志,1 为期望递归。(客户端使用)
- RA: 1 位,可用递归标志,1 为可用递归。(服务器使用)
- Z: 3 位,保留字段,必须为 0。(服务器、客户端都使用)
- RCODE: 4 位,响应码,0 为无错误,1 为格式错误,2 为服务器错误,3 为名字不存在,4 为不支持的查询,5 为拒绝查询。(服务器使用)
- QDCOUNT: 16 位,查询的问题数。
- ANCOUNT: 16 位,回答的资源记录数。
- NSCOUNT: 16 位,授权的资源记录数。
- ARCOUNT: 16 位,额外的资源记录数。
Q:为什么要有截断标志?
A:因为 UDP 单数据包的大小有限,如果查询、返回的结果太大,就会被截断。且 RFC 1035 规定 UDP 数据包长度不得超过 512 字节。
2.2 Question
Question 格式如下
1 | |
其中:
- QNAME: 查询的域名。
- QTYPE: 查询的类型。
- QCLASS: 查询的类。
2.2.1 QNAME
QNAME 是一个域名,要求格式为:
每一个 Label 前都需有 8 位的长度字段,长度字段的值为 Label 的长度。
Label 是域名的组成部分,例如www.nacldragon.top有三个 Label,分别是www、nacldragon、top,长度分别为 3、9、3。
同时,域名的最后一个 Label 必须是 0,表示域名的结束(ROOT)。
因此如果要查询www.nacldragon.top,QNAME 的值为3www9nacldragon3top0,十六进制串为 0x03 77 77 77 0a 6e 61 63 6c 64 72 61 67 6f 6e 03 74 6f 70 00。
2.2.2 QTYPE
QTYPE 是查询的类型,常用的有以下几种:
- 1: A 记录,查询域名对应的 IPv4 地址。
- 2: NS 记录,查询域名对应的域名服务器。
- 5: CNAME 记录,查询域名对应的规范名称。
- 6: SOA 记录,查询域名对应的起始授权机构。
- 12: PTR 记录,查询域名对应的规范名称。
- 15: MX 记录,查询域名对应的邮件交换服务器。
- 16: TXT 记录,查询域名对应的文本信息。
- 28: AAAA 记录,查询域名对应的 IPv6 地址。
- 33: SRV 记录,查询域名对应的服务记录。
- 252: AXFR 记录,请求区域传送。
- 255: ANY 记录,请求所有记录。
2.2.3 QCLASS
QCLASS 是查询的类,有以下几种:
- 1: IN 类,Internet 类。
- 2: CS 类,CSNET 类。
- 3: CH 类,CHAOS 类。
- 4: HS 类,Hesiod 类。
2.3 Answer
Answer 格式如下(此为 Resource Record, RR 资源记录格式)
1 | |
其中:
- NAME: 查询的域名。
- TYPE: 查询的类型。
- CLASS: 查询的类。
- TTL: 生存时间。
- RDLENGTH: RDATA 的长度。
- RDATA: 查询的数据。
2.3.1 NAME
NAME 是一个域名,格式可以和 QNAME 一样。
即每一个 Label 前都需有 8 位的长度字段,长度字段的值为 Label 的长度。
Label 是域名的组成部分,例如www.nacldragon.top有三个 Label,分别是www、nacldragon、top,长度分别为 3、9、3。
同时,域名的最后一个 Label 必须是 0,表示域名的结束(ROOT)。
因此如果要查询www.nacldragon.top,NAME 的值为3www9nacldragon3top0,十六进制串为 0x03 77 77 77 0a 6e 61 63 6c 64 72 61 67 6f 6e 03 74 6f 70 00。
但是,为了节省空间,RFC 1035 规定了一种压缩的方式,即如果一个域名在报文中出现过,那么在后续的报文中可以用指针的方式来表示这个域名。
指针共占用两个字节,具体格式如下:
1 | |
要求 OFFSET 的最高两位为 1 1,表示这是一个指针,后面的 14 位表示偏移量,且指针指向的位置为域名的第一个字节(一般是标识 Label 长度的字节)。
例如,报文在 0x00ab 处出现了www.nacldragon.top,那么在后续的报文中就可以用0xc0 ab来表示www.nacldragon.top。
因此,我们共有三种填写此字段的方式:
- 结尾是 0 的 Label 串,即用域名的方式来表示域名。
- 指针方式,即用指针的方式来表示域名。
- 结尾是指针的 Label 串,是上述两种方式的结合。
普遍情况下,由于 DNS 报文头长度固定,因此查询域名一般出现在 0x0c 处,因此 NAME 字段的值一般为0xc0 0c。
2.3.2 TYPE
TYPE 是查询的类型,和 QTYPE 一样,常用的有:
- 1: A 记录,查询域名对应的 IPv4 地址。
- 2: NS 记录,查询域名对应的域名服务器。
- 5: CNAME 记录,查询域名对应的规范名称。
- 6: SOA 记录,查询域名对应的起始授权机构。
- 12: PTR 记录,查询域名对应的规范名称。
- 15: MX 记录,查询域名对应的邮件交换服务器。
- 16: TXT 记录,查询域名对应的文本信息。
- 28: AAAA 记录,查询域名对应的 IPv6 地址。
- 33: SRV 记录,查询域名对应的服务记录。
- 252: AXFR 记录,请求区域传送。
- 255: ANY 记录,请求所有记录。
2.3.3 CLASS
CLASS 是查询的类,和 QCLASS 一样,有:
- 1: IN 类,Internet 类。
- 2: CS 类,CSNET 类。
- 3: CH 类,CHAOS 类。
- 4: HS 类,Hesiod 类。
2.3.4 TTL
TTL 是生存时间,表示资源记录的有效时间,单位为秒。
2.3.5 RDLENGTH
RDLENGTH 表示的是 RDATA 的长度。
2.3.6 RDATA
RDATA 是查询的数据,根据查询的类型不同,RDATA 的格式也不同。
2.4 Authority
这部分是指向授权服务器的资源记录,即域名的 NS 记录,主要介绍授权服务器的信息。
2.5 Additional
这部分是指向其他信息的资源记录,主要介绍 Authority Server 相关信息。