《DNS 协议分析》

发布时间 2023-11-15 01:18:00作者: 魔神八号

修订记录

版本 日期 修订人 备注
1.0 2023.02.20 魔神8号 初始版本

1 概述

域称系统(英语:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。

2 消息格式

2.1 总体格式

DNS 消息总体上分为5个部分(有些情况下其中一些是空的)。

+---------------------+
|        Header       |  # 头部区
+---------------------+
|       Question      |  # 问题区(the question for the name server)
+---------------------+
|        Answer       |  # 答案/应答资源记录区 (RRs answering the question)
+---------------------+
|      Authority      |  # 权威资源记录区(RRs pointing toward an authority)
+---------------------+
|      Additional     |  # 附加资源记录区 (RRs holding additional information)
+---------------------+
  • 头部区(始终存在)
    • 指示剩余部分中哪些存在的字段
    • 包含查询/响应标识,操作码等内容
  • 问题区
    • 含向域名服务器描述问题的字段
  • 应答/权威/附加资源记录区
    • 具有相同的格式

2.2 头部区(rfc1035)

头部区长度固定为12字节。对于每个DNS消息,首部区必须存在。

0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • ID(2B)

程序分配的16为标识符。该标识符被复制到相应的回复中,请求者可以使用它来匹配对未完成查询的回复。

  • QR(1bit)

区分消息是查询/query (0) 还是应答/response(1)。

  • OPCODE(4bit)

操作码。指定此消息的查询类型。该值由查询的发起者设置并复制到响应中。见附录 1。

  • AA(1bit)

权威答案/应答(Authoritative Answer)。仅响应中有效。指示应答的服务是权威 作用?

  • TC(1bit)

截断(truncation)。由于长度大于传输通道允许的长度而被截断。

  • RD(1bit)

期望递归(Recursion Desired)。 该位可以在查询中设置并复制到响应中。如果设置了 RD, 它会指示域名服务器递归地进行查询。递归查询支持是可选的。

  • RA(1bit)

Recursion Available。

  • Z(3bit)

预留。在所有查询和响应中必须为零。

  • RCODE(4bit)

响应码(Response code)。见附录2。

  • QDCOUNT(2B)

无符号16位整数。问题区中的条目数。

  • ANCOUNT(2B)

无符号16位整数。答案区中的资源记录数。

  • NSCOUNT(2B)

无符号16位整数。权威/授权区域名服务器的资源记录数。

  • ARCOUNT(2B)

无符号16位整数。附加区的资源记录数。

2.3头部区(rfc2535)

rfc2535 6

从 DNS 查询/响应的头部分配了两个以前未使用的位 。AD(authentic data)位在响应中指示响应的答案和权威区域包含的所有数据均已根据该服务器的策略由服务器进行了身份验证。CD(checking disabled)位在查询中指示发送查询的解析器可以接受未决(未验证)的数据。

0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • Z(1bit)

预留。在所有查询和响应中必须为零。

  • AD

TODO

  • CD

TODO

2.4 问题区

问题部分用于承载大多数查询中的“问题, 即。包含 QDCOUNT(通常为 1)个条目。
每个条目的格式如下:

0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                                               |
/                     QNAME                     /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     QTYPE                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     QCLASS                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • QNAME(变长)

表示为一系列标签的域名,其中每个标签由一个长度字节和后跟该 字节数的八位字节组成。域名以长度 为0的空标签结束(空标签即 0x00)。

The domain name terminates with the zero length octet for the null label of the root.

这里的意思可能是表示0x00空标签也是root节点。

  • QTYPE(2B)

查询类型。见附录3。

  • QCLASS(2B)

查询的类。见附录4。

2.5 资源记录区

答案、权威和附加资源记录区具有相同的格式:可变数量的资源记录,其中数量 记录在头部区中相应的计数字段中指定。
每个资源记录具有以下格式:

   0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • NAME

此资源记录所属的域名。详细信息见"消息压缩"章节。
:::info
备注:实际包文来看,资源记录中NAME 一般会采用压缩的格式,但规范中貌似没有说明一定会压缩。所以实际解析过程中需要进行判断。
:::

  • TYPE(2B)

指定 RDATA 字段中数据的含义。见附录3。

  • CLASS(4B)。

指定 RDATA 字段中数据的类别。见附录4。

  • TTL(4B)

32位无符号整数。生存时间,资源记录在被丢弃之前可以缓存的时间间隔(以秒为单位)。零值被解释为意味着 RR 只能用于正在进行的事务,不应被缓存。

  • RDLENGTH(2B)

无符号 16 位整数,指定RDATA 字段字节数。

  • RDATA(n)

描述资源的可变长度字符串。

:::info
备注:rfc1035规范中暂未发现有资源记录出现在请求/响应消息的限制说明。
实际经验来看:

  1. 三种资源记录都可能出现在响应中
  2. 附加资源记录也会出现在请求中的报文中
    :::

2.6 消息压缩

rfc1035 4.1.4

为了减小消息的大小,域名系统采用了 消除消息中重复域名的压缩方案。
在此方案中,整个域名或域名末尾的标签列表被替换为指向此前出现的相同域名的指针。

指针采用2个字节序列的形式:


0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1  1|                OFFSET                   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

前两个bit作为一个整体。可用于将指针与标签区分开,因为标签必须以两个零位开头(标签被限制为 63个字节或更少,10 和 01 组合保留供将来使用。OFFSET 字段指定从消息开始的 偏移量(即, 域标头中 ID 字段的第一个八位字节)

这里只解读了一部分规范。可能还有其它的压缩情况。

压缩方案允许将消息中的域名表示为(即域名出现的几种格式)

  • 以零八位字节结尾的标签序列
  • 指针
  • 指针结尾的标签序列

3 消息传输

3.2 UDP

UDP 消息使用端口53。UDP 携带的消息限制为 512 字节(不包括 IP 或 UDP 标头)。 较长的消息将被截断,并在标头中设置 TC 位。

3.2 TCP(TODO)

3.3 HTTP(TODO)

4 消息示例(TODO)

# 请求
Domain Name System (query)
Transaction ID: 0x0030                            # (事务)id
    Flags: 0x0000 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...0 .... .... = Recursion desired: Don't do query recursively
        .... .... .0.. .... = Z: reserved (0)
        .... .... ...0 .... = Non-authenticated data: Unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        www.cisco.com: type A, class IN
            Name: www.cisco.com
            [Name Length: 13]
            [Label Count: 3]
            Type: A (Host Address) (1)
            Class: IN (0x0001)
    [Response In: 2]


          

5 遗留问题

规范解读

rfc1035 4.1.1
Note that the contents of the answer section may have multiple owner names because of aliases. The AA bit corresponds to the name which matches the query name, or the first owner name in the answer section.

注意,由于别名的存在,答案部分的内容可能有多个所有者名称。AA位对应于与查询名称匹配的名称,或回答部分中的第一个所有者名称。

附录

1 OPCODE(操作码)

含义 规范
0 标准查询(QUERY) rfc1035
1 反向查询(IQUERY) 暂未见过报文(sunlj)
2 服务器状态请求(STATUS) 暂未见过报文(sunlj)
3~15 保留将来使用。

2 RCODE(响应码)

含义 规范
0 无错误 rfc1035
1 格式错误。域名服务器无法解释查询
2 服务器故障。由于域名服务器问题,无法处理此查询
3 名称错误。仅对来自权威名称服务器的响应有意义,此代码表示查询中引用的域名不存在
4 未实现。域名服务器不支持请求的查询类型
5 拒绝。名称服务器出于策略原因拒绝执行指定的操作。例如,域名服务器可能不希望向特定请求者提供信息,或者域名服务器可能不希望执行特定操作
6~15 保留将来使用

3 QTYPE(请求类型)

[rfc1035 3.2.2]
TYPE fields are used in resource records. Note that these types are a subset of QTYPEs.

[rfc1035 3.2.3]
QTYPE fields appear in the question part of a query. QTYPES are a superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the following QTYPEs are defined:......

TYPE 在资源记录中使用,是 QTYPE 的子集。
TYPE 字段出现在查询的问题部分。QTYPES 是一个 TYPE 的超集,因此所有 TYPE 都是有效的 QTYPE。

助记符 含义 类型 规范
1 A 主机地址(IPv4) rfc1035
2 NS 权威域名服务器
3 MD 邮件目的地址(过时,使用MX)
4 MF 邮件转发器(过时,使用MX)
5 CNAME 别名的规范名称 (canonical name)
6 SOA 起始授权区域
7 MB 邮箱域名
8 MG 邮件组成员
9 MR 邮件重命名域名
10 NULL 无效的 RR
11 WKS 已知服务描述
12 PTR 域名指针
13 HINFO 主机信息
14 MINFO 邮箱或邮件列表信息
15 MT 邮件交换
16 TXT 文本字符串
252 AXFR 请求转移整个区域 仅QTYPE
253 MAILB 对邮箱相关记录的请求(MB, MG or MR) 仅QTYPE
254 MAILA 邮件代理RR请求 仅QTYPE
255 * 请求所有记录 仅QTYPE
28 AAAA 主机地址(IPv6) rfc3596
41 OPT

rfc6891

4 QCLASS(请求类)

rfc1035 3.2.4
CLASS fields appear in resource records

rfc1035 2.2.4
QCLASS fields appear in the question section of a query. QCLASS values are a superset of CLASS values; every CLASS is a valid QCLASS.

QCLASS 字段出现在查询的问题部分。QCLASS 值 是 CLASS 值的超集;每个 CLASS 都是有效的 QCLASS

助记符 含义 类型 规范 备注
1 IN Internet rfc1035 目前见到的报文都是此值(sunlj)
2 CS CSNET 类(过时,仅用于某些过时 RFC 中的示例)
3 CH CHAOS 类
4 HS Hesiod ?
255 * 任何类 仅QCLASS

备注

/** @note
	* 从实际报文来看
	* 1. QTYPE为any时,answer中可能会出现IPv4/IPv6混合的情况。
    * 2. QTYPE为A时,answer中可能会出现IP和CNAME混合的情况。AAAA应该也是一样
    * 3. QTYPE为CNAME时,answer中可能会同时出现IP和CNAME混合的情况。
    * 4. QTYPE为NS时,目前遇到的报文中,answer中仅出现ns,附加资源记录中会出现ip。
    * 5. 请求报文中,也会存在附加资源记录。
*/


/*
    rfc6891, OPT资源记录格式(和wireshark展示的结构似乎不太一样),
    怀疑是虽然形式上各字段一致,实际上语义发生了改变。
    +------------+--------------+------------------------------+
    | Field Name | Field Type   | Description                  |
    +------------+--------------+------------------------------+
    | NAME       | domain name  | MUST be 0 (root domain)      |
    | TYPE       | u_int16_t    | OPT (41)                     |
    | CLASS      | u_int16_t    | requestor's UDP payload size |
    | TTL        | u_int32_t    | extended RCODE and flags     |
    | RDLEN      | u_int16_t    | length of all RDATA          |
    | RDATA      | octet stream | {attribute,value} pairs      |
    +------------+--------------+------------------------------+
*/


/** @note
 * 目前认为所有的资源记录,应具备相同的格式。所以即便的产生了新的类型,也会以表面上相同形式的出现。
 * 所以不需改动或少量改动即可正确跳过。对资源记录解析的影响有限。
 */

参考资料

  1. RFC1035:DNS 实施和规范 , 1987.11
  2. RFC3596:支持 IP 版本 6 的 DNS 扩展,2003.10
  3. RFC2535:域名系统安全扩展 ,1999.3
  4. RFC6891:DNS 的扩展机制 (EDNS(0))
  5. wiki:域名系统