DNS 报文
共同实现 DNS 分布式数据库的所有 DNS 服务器存储了资源记录(Resource Record, RR)
,RR 提供了主机名到 IP 地址的映射。每个 DNS 回答报文中会包含一条或多条资源记录。RR 记录用于回复客户端查询。
资源记录是一个包含了下列字段的 4 元组
(Name, Value, Type, TTL)
RR 会有不同的类型,下面是不同类型的 RR 汇总表
DNS RR 类型 | 解释 |
A 记录 | IPv4 主机记录,用于将域名映射到 IPv4 地址 |
AAAA 记录 | IPv6 主机记录,用于将域名映射到 IPv6 地址 |
CNAME 记录 | 别名记录,用于映射 DNS 域名的别名 |
MX 记录 | 邮件交换器,用于将 DNS 域名映射到邮件服务器 |
PTR 记录 | 指针,用于反向查找(IP地址到域名解析) |
SRV 记录 | SRV记录,用于映射可用服务。 |
DNS 有两种报文,一种是查询报文,一种是响应报文,并且这两种报文有着相同的格式,下面是 DNS 的报文格式
上图显示了 DNS 的报文格式,其中事务 ID、标志、问题数量、回答资源记录数、权威名称服务器计数、附加资源记录数这六个字段是 DNS 的报文段首部,报文段首部一共有 12 个字节。
报文段首部
报文段首部是 DNS 报文的基础结构部分,下面我们对报文段首部中的每个字节进行描述
- 事务 ID: 事务 ID 占用 2 个字节。它是 DNS 的标识,又叫做
标识符
,对于请求报文和响应报文来说,这个字段的值是一样的,通过标识符可以区分 DNS 应答报文是对哪个请求进行响应的。 - 标志:标志字段占用 2 个字节。标志字段有很多,而且也比较重要,下面列出来了所有的标志字段。
每个字段的含义如下
QR(Response)
: 1 bit 的 QR 标识报文是查询报文还是响应报文,查询报文时 QR = 0,响应报文时 QR = 1。OpCode
: 4 bit 的 OpCode 表示操作码,其中,0 表示标准查询,1 表示反向查询,2 表示服务器状态请求。AA(Authoritative)
: 1 bit 的 AA 代表授权应答,这个 AA 只在响应报文中有效,值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。TC(Truncated)
: 截断标志位,值为 1 时,表示响应已超过 512 字节并且已经被截断,只返回前 512 个字节。RD(Recursion Desired)
: 这个字段是期望递归字段,该字段在查询中设置,并在响应中返回。该标志告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。RA(Recursion Available)
: 可用递归字段,这个字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。zero
: 保留字段,在所有的请求和应答报文中,它的值必须为 0。AD
: 这个字段表示信息是否是已授权。CD
: 这个字段表示是否禁用安全检查。rcode(Reply code)
:这个字段是返回码字段,表示响应的差错状态。当值为 0 时,表示没有错误;当值为 1 时,表示报文格式错误(Format error),服务器不能理解请求的报文;当值为 2 时,表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求;当值为 3 时,表示名字错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在;当值为 4 时,表示查询类型不支持(Not Implemented),即域名服务器不支持查询类型;当值为 5 时,表示拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。
相信读者跟我一样,只看这些字段没什么意思,下面我们就通过抓包的方式,看一下具体的 DNS 报文。
现在我们可以看一下具体的 DNS 报文,通过 query
可知这是一个请求报文,这个报文的标识符是 0xcd28
,它的标志如下
- QR = 0 实锤了这就是一个请求。
- 然后是四个字节的 OpCode,它的值是 0,表示这是一个标准查询。
- 因为这是一个查询请求,所以没有 AA 字段出现。
- 然后是截断标志位 Truncated,表示没有被截断。
- 紧随其后的 RD = 1,表示希望得到递归回答。
- 请求报文中没有 RA 字段出现。
- 然后是保留字段 zero。
- 紧随其后的 0 表示未经身份验证的数据是不可接受的。
- 没有 rcode 字段的值
然后我们看一下响应报文
可以看到,标志位也是 0xcd28
,可以说明这就是上面查询请求的响应。
查询请求已经解释过的报文我们这里就不再说明了,现在只解释一下请求报文中没有的内容
- 紧随在 OpCode 后面的 AA 字段已经出现了,它的值为 0 ,表示不是权威 DNS 服务器的响应
- 最后是 rcode 字段的响应,值为 0 时,表示没有错误。
问题区域
问题区域通常指报文格式中查询问题的区域部分。这部分用来显示 DNS 查询请求的问题,包括查询类型和查询类
这部分中每个字段的含义如下
- 查询名:指定要查询的域名,有时候也是 IP 地址,用于反向查询。
- 查询类型:DNS 查询请求的资源类型,通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。
- 查询类:地址类型,通常为互联网地址,值为 1 。
同样的,我们再使用 wireshark 查看一下问题区域
可以看到,这是对 mobile-gtalk.l.google.com 发起的 DNS 查询请求,查询类型是 A,那么得到的响应类型应该也是 A
如上图所示,响应类型是 A ,查询类的值通常是 1、254 和 255,分别表示互联网类、没有此类和所有类,这些是我们感兴趣的值,其他值通常不用于 TCP/IP 网络。
资源记录部分
资源记录部分是 DNS 报文的最后三个字段,包括回答问题区域、权威名称服务器记录、附加信息区域,这三个字段均采用一种称为资源记录的格式,如下图所示
资源记录部分的字段含义如下
- 域名:DNS 请求的域名。
- 类型:资源记录的类型,与问题部分中的查询类型值是一样的。
- 类:地址类型、与问题中的查询类值一样的。
- 生存时间:以秒为单位,表示资源记录的生命周期。
- 资源数据长度:资源数据的长度。
- 资源数据:表示按查询段要求返回的相关资源记录的数据。
资源记录部分只有在 DNS 响应包中才会出现。下面我们就来通过响应报文看一下具体的字段示例
其中,域名的值是 mobile-gtalk.l.google.com ,类型是 A,类是 1,生存时间是 5 秒,数据长度是 4 字节,资源数据表示的地址是 63.233.189.188。
SOA 记录
如果是权威 DNS 服务器的响应的话,会显示记录存储有关区域的重要信息,这种信息就是 SOA
记录。所有 的DNS 区域都需要一个 SOA 记录才能符合 IETF 标准。SOA 记录对于区域传输也很重要。
SOA 记录除具有 DNS 解析器响应的字段外,还具有一些额外的字段,如下
具体字段含义
PNAME
:即 Primary Name Server,这是区域的主要名称服务器的名称。RNAME
:即 Responsible authority's mailbox,RNAME 代表管理员的电子邮件地址,@ 用 . 来表示,也就是说 admin.example.com 等同于 admin@example.com。序列号
:即 Serial Number ,区域序列号是该区域的唯一标识符。刷新间隔
:即 Refresh Interval,在请求主服务器提供 SOA 记录以查看其是否已更新之前,辅助服务器应等待的时间(以秒为单位)。重试间隔
:服务器应等待无响应的主要名称服务器再次请求更新的时间。过期限制
:如果辅助服务器在这段时间内没有收到主服务器的响应,则应停止响应对该区域的查询。
上面提到了主要名称服务器和服务名称服务器,他们之间的关系如下
这块我们主要解释了 RR 类型为 A(IPv4) 和 SOA 的记录,除此之外还有很多类型,这篇文章就不再详细介绍了,读者朋友们可以阅读 《TCP/IP 卷一 协议》和 cloudflare 的官网 https://www.cloudflare.com/learning/dns/dns-records/ 查阅,值得一提的是,cloudflare 是一个学习网络协议非常好的网站。