记忆 IP 地址对于普通人来说是一个非常痛苦的事情。因此互联网提供了通过 Host Name 来访问对应 host 的方法。
把 Host Name 对应到 IP 的行为称作 Name Resolution。互联网上提供 Name Resoulution 的使用最广泛的服务就是 Domain Name System(下称 DNS)。DNS 服务是互联网中最为常见的服务之一,主要提供了 IP 地址和域名的映射能力。
DNS 可以被视作一个分布式的数据库,由遍布在世界的各个角落的 DNS 服务器通过 DNS 协议提供服务。
DNS 中使用的所有名字的集合叫做 DNS Name Space。DNS Name Space 目前是一个树状的结构,根部是一个未命名的 root,
各个节点由 Domain 组成。Root 节点下面的节点叫做 Top Level Domain(TLD)。TLD 包括 generic TLDs(gTLDs), country code TLDs(ccTLDs), Internationalized country code TLDs(IDN ccTLDs),以及有特殊用处的 infrastracture TLDs(ARPA)。
DNS Name Space 中的每个管理单元,称为一个 Zone。Zone 也就是 DNS Name Space 的一个子树。Zone 的管理是层层递进的,叫做代理(Delegation)。
比如 xing.ruib.in 这个域名,不考虑 Root,由三个 Zone 组成,in.,ruib. 和 xing.,这几个 Zone 的管理可以是独立的。
Zone 的管理者应该为对应的 Zone 指定至少两台域名服务器(Name Servers 或 DNS 服务),以记录该 Zone 下包含的信息,为用户服务。
一般来讲,DNS 服务器中,一台叫做 Primary,负责记录 Zone database,剩下的叫做 Secondary, 从 Primary 中不断的同步 Zone 的信息 (Zone Transfer)。这些服务器叫做该 Zone 的 Authoritive Server,存储的信息是 Authoritive 的。
对应的,DNS 服务器也是一个树状的层级架构。最上层由管理 Root zone 的 13 组 Root Servers 组成,下面是 TLDs Name Servers 等等。通过层层递进的查询,可以找到 DNS Name Space 中的所有 Name 对应的信息。
为了查询的效率,避免每次查询都要穿透到上层 DNS Server,缓存是必不可少的。每条缓存记录都有存活时间(TTL)。缓存中的信息是 Non-authoritive 的。DNS 服务器不仅会缓存正确查询的结果,也会缓存错误查询的结果,
以避免错误的应用程序不断查询错误的域名信息,造成不必要的损耗。
客户端和 DNS 服务器、DNS 服务器之前主要利用 DNS 协议通信。DNS 协议主要包含了两大协议。一个是查询/响应 (Query/Response) 协议,主要用于查询某个特定的域名。一个用于 DNS 服务之间交换数据的 Zone Transfer 协议。
DNS 协议有一个通用的消息格式。消息本身是一个固定 12 Bytes 的消息头 + 一个变长的消息体。
消息头的组成为:
2 Bytes 的 Transaction Id, 用于客户端匹配请求和响应。
2 Bytes 的 Flags,包括: 1 bit 的 QR,标志该消息是 Query(0) 或者 Response(1)。4 bits 的 OpCode,标志当前消息的操作,有 Query(1),Notify(4),Update(5)。
1 bit 的 AA,标志当前消息是否是 Authoritive Answer。1 bit 的 TC,标志当前消息是否被 Truncated。1 bit 的 RD(Recursion Desired),标志是否要求递归查询。
1 bit 的 RA(Recursion Available),当前服务器是否支持递归查询。1 bit 的 Z(Zero),保留标志位。2 bit 的 AD(Authentic Data) 和 CD(Checking Disabled),用于安全性校验。4 bits 的 Rcode,错误码。
还有 8 Bytes 的 Query Count/Zone Count, Answer Count/Prerequisite Count, Authority Record Count/Update Count 和 Additional Information Count,记录消息体的 RR 数量。
DNS 消息的可变长度部分包含了 Questions 和 Resource Records(RR)。每一个 Question 和 RR 开始都是一个 Name,即域名。Name 本身由一个个 label 组成。
为了减少体积,Label 又分为 Data Label 和 Compression Label。Data Label 是 Name 中的一段数据,Compression Label 是指向 Data Label 的指针。
对于 Query 消息,DNS 通常使用 UDP 协议,消息超过 512 Bytes 时便会将消息头的 TC 设为 1,并将消息截断。对于需要大块传输信息的场合,如 Zone Transfer,DNS 使用 TCP 协议。
流行的 DNS 协议的 RR 类型有如下几种:
-
A
- IPV4 Address Record
-
NS
- Authoritive Name Server
-
CNAME
- canonical name, to name aliasing
-
SOA
- start of autority,包含当前 Zone 的权威信息(如 name servers, 管理者的邮箱地址等等)
-
PTR
- IP 地址到 name 的映射。
-
MX
- Mail Exchanger
-
TXT
- Text,文本信息
-
AAAA
- IPV6 Address Record
-
SRV
- Server Selection
-
NAPTR
- Name Authoriy Pointer, 以支持可选的 Name Space。
-
OPT
- 伪 RR,用于扩展 DNS 协议,参见 EDNS0。
-
IXFR
- incremental zone transfer
-
AXFR
- Full zone transfer
-
ANY
- Request all records
更新 DNS 记录,可以向对应 Zone 的 Authoritive Server 发送 DNS UPDATE 消息。DNS UPDATE 需要指定 prerequites,其中的条件如果不满足,DNS Server 不会更新消息。DNS Server 会根据消息来增加/删除自己存储的 RR(更改需要删除 RR 并增加新的 RR)。
为了保证服务之前数据的同步,DNS Server 之前需要进行 Zone Transfer。最开始,Zone Transfer 通过轮询进行。为了解决不必要的消耗(可能很长时间,Zone 的信息不会被更改),异步的方法被提出。
当 Zone 的信息被更改后,主 DNS Server 会发送 DNS Notify 的消息到监听更改的服务器,重新进行 Zone Transfer。Zone Transter 又分为全量和增量。