深入解析DNS请求与响应报文—基于RFC1035的逐字节分析
深入解析DNS请求与响应报文 — 基于RFC1035的逐字节分析
在网络通信中,DNS(域名系统)扮演着至关重要的角色,主要负责将人类可读的域名转换为机器可读的IP地址。DNS默认使用UDP协议进行查询,因为UDP具有较低的延迟和开销,适合快速的请求-响应模式。然而,在以下情况下,DNS会使用TCP协议:
- 当响应数据超过512字节时(在DNS中,如果使用EDNS0,最大可以达到4096字节)。
- 当进行区域传送(zone transfer)时,通常用于DNS服务器之间的同步。
- 当请求需要保证可靠性(如在某些复杂的查询中)。
在这篇博客中,我们将结合RFC1035的规范,详细分析DNS请求与响应报文的格式与内容。我们将涵盖以下内容:
- DNS数据帧格式(基于RFC1035)。
- DNS资源记录(RR)格式(基于RFC1035)。
- 逐字节分析DNS请求与响应报文,并结合以上两点进行详细解析。
1. DNS 数据帧格式(根据RFC 1035)
在深入分析DNS请求和响应报文之前,我们先了解一下DNS数据帧的整体结构。基于RFC1035,DNS数据帧的格式可以分为以下几个部分:
+---------------------+
| Header | 固定12字节,包含标识符、标志位、计数器等
+---------------------+
| Question | 可变长度,包含查询的域名、查询类型等
+---------------------+
| Answer | 可变长度,包含资源记录(RR)的回答部分
+---------------------+
| Authority | 可变长度,包含权威名称服务器信息(如果有)
+---------------------+
| Additional | 可变长度,包含附加信息(如果有)
+---------------------+
DNS数据帧各部分说明:
- Header:包含ID、标志位、问题数、回答数、权威记录数、附加记录数等。
- Question:用于客户端查询的域名信息。
- Answer:服务器返回的查询结果(例如A记录、CNAME记录等)。
- Authority:指示权威名称服务器的信息。
- Additional:可能包含额外的资源记录或其他附加信息。
DNS数据帧头部格式
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID | 16 位标识符
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | 标志字段
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT (问题计数) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT (回答计数) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT (权威记录计数) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT (附加记录计数) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- ID:唯一标识DNS查询和响应报文的16位标识符。
- Flags:包含各种标志位(QR表示查询或响应,Opcode表示操作码,AA为授权应答,RD为递归请求等)。
- QDCOUNT:问题部分的数量。
- ANCOUNT:回答部分的数量。
- NSCOUNT:权威部分的数量。
- ARCOUNT:附加部分的数量。
DNS报文中的四个部分
- 问题部分:
- 包含查询名称、类型和类。
- 回答部分:
- 包含问题的回答,如IP地址、CNAME等。
- 权威部分:
- 包含授权服务器的信息。
- 附加部分:
- 提供额外的资源记录(RR)。
2. DNS 资源记录(RR)格式
在上一章节中,我们介绍了DNS数据帧的整体结构,其中Answer、Authority和Additional部分都可能包含资源记录(Resource Records, RR)。资源记录是DNS响应中用来携带域名解析结果的核心组成部分。
每个资源记录遵循相同的结构,定义了域名信息、类型、TTL(生存时间)和实际的数据值。为了理解DNS的响应内容,我们需要先掌握RR格式的具体组成部分。
资源记录(RR)是DNS报文的核心内容,描述了域名相关的数据。RR的格式如下:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ NAME / 域名
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE | 资源类型
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS | 资源类(通常为IN)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL | 生存时间
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH | 数据长度
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ RDATA / 资源数据
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- NAME:域名,采用压缩格式或标签形式存储。
- TYPE:记录类型(如A、CNAME、MX等)。
- CLASS:资源类,通常为IN(表示互联网类)。
- TTL:生存时间,以秒为单位,指示缓存记录的时长。
- RDLENGTH:资源数据的长度。
- RDATA:资源数据,根据类型不同,内容也不同。
3. 逐字节分析DNS请求报文
以下是一个DNS请求报文的示例:
0000 a1 d2 13 84 7c 6a 51 e2 33 34 8a 22 08 00 45 00
0010 00 48 e2 ea 00 00 40 11 f1 f7 c0 a8 01 10 df 05
0020 05 05 e5 f0 00 35 00 34 2b 94 2e 45 01 00 00 01
0030 00 00 00 00 00 00 0c 73 61 66 65 62 72 6f 77 73
0040 69 6e 67 06 75 72 6c 73 65 63 02 71 71 03 63 6f
0050 6d 00 00 01 00 01
逐字节分析
我们将报文分为以太网帧、IP头部、UDP头部和DNS报文部分。
以太网帧头部
0000 a1 d2 13 84 7c 6a // 目的MAC地址
0006 51 e2 33 34 8a 22 // 源MAC地址
000C 08 00 // 以太网类型,0800表示IPv4
IP头部
000E 45 00 // 版本(IPv4)和头部长度
0010 00 48 // 总长度(72字节)
0012 e2 ea // 标识符
0014 00 00 // 标志和片偏移
0016 40 // TTL(64)
0017 11 // 协议(17,表示UDP)
0018 f1 f7 // IP头部校验和
001A c0 a8 01 10 // 源IP地址(192.168.1.16)
001E df 05 05 05 // 目的IP地址(223.5.5.5)
UDP头部
0022 e5 f0 // 源端口(58864)
0024 00 35 // 目的端口(53,DNS)
0026 00 34 // 长度(52字节)
0028 2b 94 // 校验和
DNS报文头部
002A 2e 45 // Transaction ID(随机生成)
002C 01 00 // 标志位,表示标准查询
002E 00 01 // QDCOUNT(1个问题)
0030 00 00 // ANCOUNT(无回答)
0032 00 00 // NSCOUNT(无权威记录)
0034 00 00 // ARCOUNT(无附加记录)
DNS问题(Question)部分
0036 0c 73 61 66 65 62 72 6f 77 73 69 6e 67 // 查询的域名(safebrowsing)
0042 06 75 72 6c 73 65 63 // 域名(urlsec)
0048 02 71 71 // 域名(qq)
004B 03 63 6f 6d 00 // 域名(com)
004F 00 01 // 查询类型(A记录)
0051 00 01 // 查询类(IN,互联网类)
4. 逐字节分析DNS响应报文
以下是一个DNS响应报文的示例:
0000 51 e2 33 34 8a 22 a1 d2 13 84 7c 6a 08 00 45 00
0010 00 98 e2 ea 00 00 77 11 ba a7 df 05 05 05 c0 a8
0020 01 10 00 35 e5 f0 00 84 00 00 2e 45 81 80 00 01
0030 00 03 00 00 00 00 0c 73 61 66 65 62 72 6f 77 73
0040 69 6e 67 06 75 72 6c 73 65 63 02 71 71 03 63 6f
0050 6d 00 00 01 00 01 c0 0c 00 05 00 01 00 00 00 44
0060 00 24 0c 69 6e 73 2d 33 74 6d 77 62 72 34 71 03
0070 69 61 73 0d 74 65 6e 63 65 6e 74 2d 63 6c 6f 75
0080 64 03 6e 65 74 00 c0 38 00 01 00 01 00 00 00 44
0090 00 04 2a 51 96 c9 c0 38 00 01 00 01 00 00 00 44
00a0 00 04 2a 51 96 ca
逐字节分析
以太网帧头部
0000 51 e2 33 34 8a 22 // 目的MAC地址
0006 a1 d2 13 84 7c 6a // 源MAC地址
000C 08 00 // 以太类型,0800表示IPv4
IP头部
000E 45 00 // 版本(IPv4)和头部长度
0010 00 98 // 总长度(152字节)
0012 e2 ea // 标识符
0014 00 00 // 标志和片偏移
0016 77 // TTL(119)
0017 11 // 协议(17,表示UDP)
0018 ba a7 // IP头部校验和
001A df 05 05 05 // 源IP地址(223.5.5.5)
001E c0 a8 01 10 // 目的IP地址(192.168.1.16)
UDP头部
0022 00 35 // 源端口(53,DNS)
0024 e5 f0 // 目的端口(58864)
0026 00 84 // 长度(132字节)
0028 00 00 // 校验和
DNS报文头部
002A 2e 45 // Transaction ID(0x2e45)
002C 81 80 // 标志位,表示这是响应,QR=1,标准响应
002E 00 01 // QDCOUNT(1个问题)
0030 00 03 // ANCOUNT(3个回答)
0032 00 00 // NSCOUNT(0个权威记录)
0034 00 00 // ARCOUNT(0个附加记录)
DNS问题(Question)部分
0036 0c 73 61 66 65 62 72 6f 77 73 69 6e 67 // 查询的域名(safebrowsing)
0042 06 75 72 6c 73 65 63 // 域名(urlsec)
0048 02 71 71 // 域名(qq)
004B 03 63 6f 6d 00 // 域名(com)
004F 00 01 // 查询类型(A记录)
0051 00 01 // 查询类(IN,互联网类)
回答部分(Answer Section)
0053 c0 0c // 指向问题部分的指针,表示名称(safebrowsing)
0055 00 05 // 类型(CNAME,0x0005)
0057 00 01 // 类(IN,0x0001)
0059 00 00 00 44 // TTL(68秒)
005D 00 24 // RDLENGTH(36字节)
005F 0c 69 6e 73 2d 33 74 6d 77 62 72 34 71 03 // RDATA(ins-3tmwbr4q.)
0070 69 61 73 0d 74 65 6e 63 65 6e 74 2d 63 6c 6f 75
0080 64 03 6e 65 74 00 // RDATA(tencent-cloud.net)
在这个回答部分中,第一条记录是CNAME记录,指向**ins-3tmwbr4q.tencent-cloud.net
**。
接下来是第二条记录:
0080 c0 38 // 指向问题部分的指针,表示名称(tencent-cloud.net)
0082 00 01 // 类型(A,0x0001)
0084 00 01 // 类(IN,0x0001)
0086 00 00 00 44 // TTL(68秒)
008A 00 04 // RDLENGTH(4字节)
008C 2a 51 96 c9 // RDATA(42.81.150.201)
- 第二条记录:A记录为
42.81.150.201
。
然后是第三条记录:
0090 c0 38 // 指向问题部分的指针,表示名称(tencent-cloud.net)
0092 00 01 // 类型(A,0x0001)
0094 00 01 // 类(IN,0x0001)
0096 00 00 00 44 // TTL(68秒)
009A 00 04 // RDLENGTH(4字节)
009C 2a 51 96 ca // RDATA(42.81.150.202)
- 第三条记录:A记录为
42.81.150.202
。
解析结果
- 第一条记录:CNAME为
ins-3tmwbr4q.tencent-cloud.net
。 - 第二条记录:A记录为
42.81.150.201
。 - 第三条记录:A记录为
42.81.150.202
。
分析小结
在分析完请求和响应的报文后,我们发现以下几点:
- 请求报文的ID(Transaction ID)用于匹配请求与响应。响应中包含相同的ID,确保请求者能够识别响应。
- 响应报文中包含多个答案(ANCOUNT),表示该查询可能对应多个结果。在这个例子中,提供了CNAME记录和相应的目标域名。
- **资源记录(RR)**的每个部分都严格遵循RFC 1035的定义,包括NAME、TYPE、CLASS、TTL、RDLENGTH和RDATA字段。
最后
通过逐字节分析DNS请求与响应报文,我们可以深入了解DNS的工作原理和报文结构。结合RFC 1035中的规范,能够更好地理解DNS如何在网络中执行域名解析任务。希望这篇博客对你理解DNS协议有帮助!