浅谈 DNS 的解析

DNS 这个东西大概是个网民就听过,然而大部分人对它的观念停留在“能上 QQ 上不了网站就改 DNS 试试”的程度上,DNS 系统的结构和基本的查询流程是非常经典的程序员面试题,实际上我也被问到过,听说 SA 入职培训还有 DNS 相关课程的时候我还很吃惊这有什么好培训的,然后没几天自己就踩了 DNS 的坑,发现这里面能谈的东西还是不少而且我自己很多概念也并不是很清楚

DNS 的全程是 domain name service,关于域名系统和 DNS 出现的缘由不在此细讲,首先来说说什么是域(domain)和域名(domain name),这些内容定义在 RFC1034 和 RFC1035,先看看维基百科这个图:Domain_name_space.svg

域名的系统(域名空间)是一个树状结构,其中被虚线框起来的就是一个域,域从层次上看有域和子域的关系,如 www.example.com  中, .com  是顶级域(TLD), .example.com  是 .com  的子域,一个完整的域名从左到右从最小子域开始,以根 . 结束,完整记法是 www.example.com. ,这样的域名被称为 FQDN(Fully Qualified Domain Name,完全资格域名),但是实际使用中绝大多数我们使用的工具会自动加上末尾的点号;特别地,使用 * 可以代表该域上的所有域名,比如 *.example.com 匹配  a.b.example.com 和  a.example.com ,需注意 DNS 中的通配符(RFC 4592)和 SSL 证书中的通配符(RFC 2459),二者的定义和范围有区别,前者是全部匹配,后者是只匹配一级,不应混淆。

谈完了域和域名我们来看看域名的解析, DNS 系统是一个典型的 C/S 架构系统,在客户机上进行 DNS 查询的进程被称为 Resolver,负责处理将域名翻译成 IP 的整个过程,resolver 可以是访问网站的进程本身,也可能是系统的 DNS 解析模块,这取决于具体情况;接收查询请求的服务端被称为 Name Server,在 Server 上存储的信息被称为记录(Record),这里不展开详细讲 DNS 的各种 Record,本篇只涉及返回域名对应 IP 的 A 记录(Address)和返回下一步查询服务器的 NS 记录(Name Server),并且由于 Server 这个词的含义可以是单个服务器也可以是抽象的服务提供者,而在 DNS 中,Server 可以是一组服务器,在下面的描述中,我将有意区分 服务器 和抽象概念 Name Server

只以 Linux 为例,一般都有一个  /etc/resolv.conf ,以

这样的形式写出本机使用的 DNS 服务器地址,其他类 Unix 系统可能存在区别,比如 OS X 里绝大多数情况并不使用这个文件。

DNS 协议运行在熟知端口53,DNS 虽然常被拿来作为 UDP 协议的典型例子,但是实际上它可以使用 UDP 和 TCP,只是默认情况下使用 UDP,在超过512字节限制后才会使用 TCP,当然也可以强制 DNS 走 TCP 协议。

世界上域名这么多(据说有3亿),每天有2500亿次 DNS 查询,不可能有什么服务器可以承受的了这么大的访问量,那么怎么办呢,解决途径有两个:高速缓存和分布式数据库。

缓存很好理解,就是在一段时间内保存域名解析的结果,这段时间内直接使用上次的解析结果而不重新发起请求,这个时间在 DNS 里称为 TTL;分布式数据库的含义是,每层次的 Name Server 只负责本层次上的域的记录,最上层的是根域服务器(Root Server),那么,那么分布式数据库是如何工作的呢?在展开这部分之前,我们先要讨论一下什么是权威 Name Server 和非权威  Name Server(Authoritative name server & Non-authoritative name server):

权威 Name Server 是一个 DNS 响应的源头,是被域管理员所设置的,每个域都必须存在一组权威服务器,并以 NS 记录保存在上级 Name Server 中(在购买域名的时候一般 NS 记录就是域名商的 Name Server,此时权威服务器就是注册商的 Name Server,NS 记录可以在域名商那里进行修改),权威 Name Server 进行响应时,会在 DNS 报文中添加 AA 标志位以表示权威应答;但是问题来了,每个域的权威服务器都是域管理员手动设置的,数量非常有限,那岂不是解析一个域名可能要把请求发到地球另一边去?当然不需要,因为我们也有非权威 Name Server,比如我们的宽带运营商就提供非权威的 DNS 解析服务,当我们将 DNS 请求发送给一个非权威 Server 的时候,如果之前有人向这台服务器请求过这个域名且在缓存有效时间内,这台服务器就可以直接返回结果,并在报文中以标志位标注为 Non-authoritative answer。

那么回到之前提到的分布式数据库是如何工作的问题,非权威 Server 的缓存是哪里来的呢?那么现在就要说一说 DNS 查询的几个工作模式了,resolver 在执行解析的时候,有三种不同的解析方式,非递归(non-recursive query)、递归(recursive query)、迭代(iterative query):

  • 迭代:是最基本的 DNS 工作方式,客户端向 Server 发送查询请求,如果 Server 没有缓存,则返回能进行下一步解析的 Server 的地址,直到查到具体 IP 记录为止,比如查询  www.baidu.com,最顶级的根服务器返回负责 .com 的 Name Server, .com 的 Server 返回  .baidu.com 的 Name Server, .baidu.com 的 Name Server 返回  www.baidu.com 的具体地址。迭代查询的优点是权威 Name Server 知道请求的客户端具体 IP,利于 CDN 定位分流,但是缺点也很明显,需要客户端进行一次又一次地查询,且会一直追溯到权威 Server,费时费力;

iterative dns query

  • 递归:有人可能发现这个问题,上面说的迭代查询根本没有发挥出非权威 Server 的就近优势啊,客户端还是需要向很远的服务器进行查询那还要非权威 Server 干嘛?实际上我们有递归查询解决这个问题,假设 resolver 设置 nameserver 为 A,向 A Server 发送一个递归查询请求,A Server 代替客户进行迭代查询,A 自己作为客户端,向 DNS 根服务器、子域服务器依次发送请求得到最终结果后直接返回给客户端需要的解析结果,此时 A 被称为递归服务器(此时的 A 常为运营商或者大型 IDC 的服务器,常具有大带宽和优秀的国际出口,由 A 代为向权威查询往往比用户自行跨国访问权威服务器快很多)。如果 A 之前有查询过这个域名并在 TTL 内,则直接返回缓存中的内容。递归查询优点明显,快速、省时省力,缺点也很明显,时效性差,上游的更新可能不能及时地反应到客户查询的结果,还不利于 CDN 的调度分流,因为对于 CDN 厂商的权威 Server,他们看到的是非权威 Server 的请求,并不知道真正要访问网站的客户是谁,这个问题具体可以参见 Hostker DNS 智能调度原理

recursive dns query

  • 非递归:客户端在请求报文中设置 RD 标志位表示“我不希望得到递归的回答”;

需注意这三种方式不是完全对立的,resolver 具体使用哪种解析方式取决于 resolver 本身的支持情况,可以进行递归查询的 resolver 被成为 recursive resolver,反之被称为 stub resolver,recursive resolver 也可以进行迭代查询, 但是 stub resolver 不能进行递归查询,http://stackoverflow.com/questions/9966280/difference-between-recursive-and-iterative-dns-lookup 提到,一般 stub resolver 是被直接编译进程序的网络库。实际上怎么处理请求结果也取决于服务器的配置,如果请求的非权威 Server 不支持递归查询,一般会 fallback 到迭代查询,非权威服务器会返回一个他认为可以查到这个域名的 DNS Server(通常就是 Root Server 啦),让客户端向这个 Server 查询。


之前配置 UDP 健康检测时候手写 payload 的时候遇到的神奇问题,大概就是在 dnsmasq 处理同时带有 Recursive desired flag 和 Non-authoritative data unacceptable flag 的时候的问题。

4条评论


  1. 递归:有人可能发现这个问题,*递归查询*根本没有发挥出非权威 Server 的就近优势啊,客户端还是需要向很远的服务器进行查询那还要非权威 Server 干嘛?

    此处似乎应该为迭代查询

    回复

    1. 我想把 dnsmasq 换掉的时候导师说别折腾这个了我们换个题目。DNSSEC 这个玩意实用性太低了

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.