网络协议之DNS协议

https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Dns-raum.svg/800px-Dns-raum.svg.png

DNS协议

DNS协议的作用是通过域名查询到对应的IP地址,DNS协议依赖UDP/TCP协议实现(UDP较多)。

DNS协议包

DNS报文分为请求应答两种,结构是类似的,其中头部的大小固定为12字节,其他部分大小不固定,记录数可多可少,数目保存在头部中,大致分为五部分:

  • 头部(header),描述报文类型,以及其下 4 个小节的情况;
  • 问题节(question),保存查询问题;
  • 答案节(answer),保存问题答案,也就是查询结果;
  • 授权信息节(authority),保存授权信息;
  • 附加信息节(additional),保存附加信息;
 1|<-------------------16 bits------------------->|
 2
 30                       8                       16
 4+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   ---
 5|                       ID                      |    ^              
 6+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
 7|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |    |
 8+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
 9|                  QDCOUNT                      |    |
10+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   HEADER 12 bytes
11|                  ANCOUNT                      |    |
12+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
13|                  NSCOUNT                      |    |
14+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
15|                  ARCOUNT                      |    v
16+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   ---
17|                  NAME                         |    ^
18|                  ......                       |    |
19+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
20|                  TYPE                         |    |
21+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
22|                  CLASS                        |    |
23+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   QUERY * N
24|                  NAME                         |    |
25|                  ......                       |    |
26+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
27|                  TYPE                         |    |
28+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
29|                  CLASS                        |    v
30+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   ---
31|                  NAME                         |    ^
32|                  ......                       |    |
33+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
34|                  TYPE                         |    |
35+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
36|                  CLASS                        |    |
37+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
38|                                               |    |
39+                  TTL                          +    |
40|                                               |    |
41+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
42|                  RESOURCE LENGTH              |    |
43+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
44|                  RESOURCE                     |    |
45|                  ......                       |    |
46+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   ANSWER * N
47|                  NAME                         |    |
48|                  ......                       |    |
49+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
50|                  TYPE                         |    |
51+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
52|                  CLASS                        |    |
53+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
54|                                               |    |
55+                  TTL                          +    |
56|                                               |    |
57+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
58|                  RESOURCE LENGTH              |    |
59+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+    |
60|                  RESOURCE                     |    |
61|                  ......                       |    v
62+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+   ---

请求

HEADER部分的大小固定为12字节。

  • ID: 一个16位的ID,在应答中原样返回,以此匹配请求和应答;
  • 标识信息
    • QR: 位标记报文是一个查询请求,还是查询应答,0表示查询请求,1表示查询应答;
    • Opcode: 占4比特位,表示操作类型,0表示标准查询,1表示反向查询,2表示服务器状态请求;
    • AA(authoritative answer): 标识权威回答,表示当前查询结果是由域名的权威服务器返回的;
    • TC(truncated): 标识截断,如果查询应答超过512字节,则只返回前512字节;
    • RD(recursion desired): 标识期望递归,在查询请求中设置,并在查询应答中返回,为1时,如果服务器没有授权回答,则需要服务器替客户端请求其他DNS服务器,即递归查询,为0时,如果服务器没有授权回答,就返回一个可以处理此请求的NS服务器列表给客户端,由客户端请求其他服务器查询,即迭代查询
    • RA(recursion available): 标识服务器是否支持递归查询;
    • Z: 保留比特位,暂没有使用,必须为0
    • RCODE(response code): 占用4比特位,0表示正常,3由权威服务器返回,表示带查询域名不存在;
  • QDCOUNT: 问题记录数
  • ANCOUNT: 答案记录数
  • NSCOUNT: 权威信息记录数
  • ARCOUNT: 附加信息记录数
QUERY

QUERY部分的大小是不固定的,其中内容为NAME|TYPE|CLASS的列表,一个NAME|TYPE|CLASS的组合称为问题记录,条数记录在HEADER中,所以DNS协议支持一次查询多个域名的地址,但通常只查询一个。 问题记录由3个部分组成:

  • NAME: 待查询的域名,字段长度不固定,由域名的长度决定;
  • TYPE: 查询类型,
    • 1表示查询A(Address)记录,即IPv4地址;
    • 2表示查询NS记录,即域名服务器地址;
    • 5表示查询CNAME记录;
    • 15表示查询MX地址,即邮件发送交互地址;
    • 16表示查询TEXT文本信息;
    • 28表示查询AAAA记录,即IPv6地址;
  • CLASS: 通常为1,表示TCP/IP互联网地址; NAME部分的保存格式为以域名中的.为间隔,保存字符数和字符,例如: www.baidu.com会保存为[0x03][w][w][w][0x05][b][a][i][d][u][0x03][c][o][m][0x00]其中[]表示1字节,所以,每一级域名的长度理论上最大支持255个字符。

回复

域名服务器处理查询请求之后,需要想客户端发送回复报文,域名查询结果作为资源记录保存在答案以及后两节中。 资源记录的回复由一条或多条记录组成,所以占用的大小也不固定,一共有六个部分组成,前三个和问题记录完全一样:

  • NAME: 待查询的域名,与问题记录中一致;
  • TYPE: 查询类型,与问题记录中一致;
  • CLASS: 与问题记录一致;
  • TTL: 缓存有效时长;
  • RESOURCE LENGTH: 查询结果的长度;
  • RESOURCE: 查询结果;

域名压缩

从回复的报文来看,域名会在问题记录和答案记录中都存储一份,这样就造成了同样的内容存储了多份,为了节省报文空间,会将重复的域名进行压缩,具体的做法为: 当域名在报文中第二次出现时,只用两个字节来保存,第一个字节最高的两个比特位为0b11,剩下的部分和第二个字节组合在一起,表示该域名第一次出现在报文中的偏移量,通过偏移量即可找到该域名的具体内容;

抓包分析

命令:sudo tcpdump -i eno1 -n -t -s 512 port 53 -X+dig -t A www.qq.com

 1IP 10.4.244.42.33684 > 10.4.192.27.53: 61677+ [1au] A? www.qq.com. (51)
 2	0x0000:  4500 004f 9a51 0000 4011 17ff 0a04 f42a  E..O.Q..@......*
 3	0x0010:  0a04 c01b 8394 0035 003b c89a f0ed 0120  .......5.;......
 4	0x0020:  0001 0000 0000 0001 0377 7777 0271 7103  .........www.qq.
 5	0x0030:  636f 6d00 0001 0001 0000 2910 0000 0000  com.......).....
 6	0x0040:  0000 0c00 0a00 0801 b6d5 ad4f 189a a5    ...........O...
 7IP 10.4.192.27.53 > 10.4.244.42.33684: 61677 2/0/1 CNAME ins-r23tsuuf.ias.tencent-cloud.net., A 42.81.179.153 (103)
 8	0x0000:  4500 0083 7201 0000 7c11 041b 0a04 c01b  E...r...|.......
 9	0x0010:  0a04 f42a 0035 8394 006f 7d39 f0ed 8180  ...*.5...o}9....
10	0x0020:  0001 0002 0000 0001 0377 7777 0271 7103  .........www.qq.
11	0x0030:  636f 6d00 0001 0001 c00c 0005 0001 0000  com.............
12	0x0040:  0001 0024 0c69 6e73 2d72 3233 7473 7575  ...$.ins-r23tsuu
13	0x0050:  6603 6961 730d 7465 6e63 656e 742d 636c  f.ias.tencent-cl
14	0x0060:  6f75 6403 6e65 7400 c028 0001 0001 0000  oud.net..(......
15	0x0070:  008a 0004 2a51 b399 0000 290f a000 0000  ....*Q....).....
16	0x0080:  0000 00

通过tcpdump抓取DNS请求和回复的IP包,这里只关注DNS的包内容,所以需要忽略IP和UDP协议的头部,将IP和UDP的头部摘除如下: 请求

1f0ed 0120 0001 0000 0000 0001 0377 7777
20271 7103 636f 6d00 0001 0001 0000 2910
30000 0000 0000 0c00 0a00 0801 b6d5 ad4f
4189a a5
  • 0xf0ed前16字节,为DNS报文的ID,即61677;
  • 0x0120=0b0000000100100000,首位0表明查询请求,0000表明标准查询,0010表明期望递归查询;
  • 0x0001表示查询的记录数为1条;
  • 0x0001表示附加信息有1条;
  • 0x0377 0x7777 0x0271 0x7103 0x636f 0x6d00按字节可翻译为[0x03][w][w][w][0x02][q][q][0x03][c][o][m][0x00]
  • 0x0001表示查询类型为A
  • 0x0001查询类;
  • 0x0000 0x2910 0x0000 0x0000 0x0000OPT记录(Option Record)是一种特殊的DNS记录类型,用于支持扩展的DNS功能。OPT记录在RFC 2671中被定义,是为了支持EDNS(扩展的DNS)而引入的。它允许DNS请求和响应中包含扩展的信息,而不改变现有的DNS消息格式;
  • 0x0c00 0x0a00 0x0801 0xb6d5 0xad4f 0x189a 0xa5表示附加数据; 回复
1f0ed 8180 0001 0002 0000 0001 0377 7777
20271 7103 636f 6d00 0001 0001 c00c 0005
30001 0000 0001 0024 0c69 6e73 2d72 3233
47473 7575 6603 6961 730d 7465 6e63 656e
5742d 636c 6f75 6403 6e65 7400 c028 0001
60001 0000 008a 0004 2a51 b399 0000 290f
7a000 0000 0000 00
  • 0xf0ed前16字节,为DNS报文的ID,即61677;
  • 0x8180=0b1000000110000000,首位1表名回复报文,0000表示标准查询,0011表示递归查询且服务器支持递归查询;
  • 0x0001查询记录数为1;
  • 0x0002查询结果数为2;
  • 0x0000表示权威记录数为0;
  • 0x0001附加资源数为1;
  • 0x0377 0x7777 0x0271 0x7103 0x636f 0x6d00为查询域名记录;
  • 0x0001表示查询类型为A
  • 0x0001查询类;
  • 0xc00c表示查询的域名,因为域名重复出现所以这里对域名进行了压缩,即域名的实际位置为报文偏移0x0c的位置,即0x0377 0x7777 0x0271 0x7103 0x636f 0x6d00
  • 0x0005表示该条答案记录类型为CNAME记录;
  • 0x0001查询类;
  • 0x0000 0x0001表示TTL为1秒;
  • 0x0024表示当前答案记录资源的长度为36字节;
  • 0x0c69 0x6e73 0x2d72 0x3233 0x7473 0x7575 0x6603 0x6961 0x730d 0x7465 0x6e63 0x656e 0x742d 0x636c 0x6f75 0x6403 0x6e65 0x7400根据域名的存储规则翻译为[0x0c][i][n][s][-][r][2][3][t][s][u][u][f][0x03][i][a][s][0x0d][t][e][n][c][e][n][t][-][c][l][o][u][d][0x03][n][e][t][0x00]
  • 0xc028表示查询的域名,报文偏移0x28的位置,即第一条记录中CNAME结果域名的位置;
  • 0x0001表示查询类型为A
  • 0x0001查询类;
  • 0x0000 0x008a表示TTL为138秒;
  • 0x0004表示资源长度为4字节,即IPv4的固定大小;
  • 0x2a51 0xb399通过点分十进制将32位的IP可翻译为42.81.179.153
Latest Posts