陈鸽 阿里云智能GTS-SRE团队 技术专家

曾就职于微软负责Windows操作系统网络协议栈及网络产品技术支持相关工作,了解各产品标准协议例如TCPIP、DNS等。现就职于阿里云智能GTS-SRE团队,负责专有云网络相关产品(SLB/VPC等)的高可用、高可靠运维。

引言

上一期我们基本上将客户端的查询行为及其特性尽可能地梳理了一次,而本期我们关注DNS服务器部分。由于DNS协议本身已经有相当详细的分析了,本文将不再赘述,若感兴趣可直接在Internet搜索。推荐关注DNS RFC,可参考文后资料了解详情 (1)

与DNS协议工作

多数DNS服务提供商有各自的DNS服务应用来提供名称解析功能,一般来说此类应用最主要的是完成标准DNS协议,并提供较好的性能、完善的日志服务以及特殊的GEO解析等高级功能。针对DNS服务,各家产品的实现虽各不相同,但总体解析的过程是一定符合协议标准的。下面分别看一下Windows的DNS服务和Linux的Bind应用。

  • Windows DNS server服务

    DNS标准协议定义的两种查询方式在Windows的DNS server服务中支持得很好。自Windows NT开始,DNS server总是一个基础服务带在server的发行版中,历经多次升级,功能相当全面。由于与Windows的AD完全整合,Windows DNS server功能复杂,适合内网使用。其功能简单罗列如下:

    图1:Windows DNS server功能展示
  • Linux Bind应用
    在Linux上Bind(Berkeley Internet Name Domain)应用提供了完善的DNS功能,其功能相对简单,但性能较好,我们简单将其作为本地DNS服务学习和研究。Bind是实现DNS协议的一种开放源码软件,已经成为使用最广泛的DNS服务器软件,它包含对域名的查询和响应所需的所有软件。与Windows DNS类似,BIND软件包包括以下主要的几个部分:
    • DNS服务器:这是一个叫做named的程序,代表name daemon的简写。它根据DNS协议标准的规定,响应收到的查询。
    • DNS解析库(resolver library):一个解析器是一个程序,通过发送请求到合适的服务器并且对服务器的响应做出合适的回应,来解析对一个域名的查询。一个解析库是程序组件的集合,可以在开发其它程序时使用,为这些程序提供域名解析的功能。

DNS服务器配置建议

  • DNS查询行为配置细节
    • Iterative Query迭代查询

      迭代查询是DNS名称解析的基础,一般情况下,DNS server使用迭代查询,根据root-hints server的响应一级一级得到最终结果。与迭代查询相关的配置项如下:

      Windows:
          root-hints server配置:C:\Windows\System32\dns\cache.dns
          NoRecursion开关:dnscmd /config /NoRecursion
          root zone配置:Create a .(dot) zone
      
      Linux Bind:
          默认使用Iterative Query,除非在named.conf中配置forwarders

      注:root zone的创建将会使DNS服务拒绝所有转发查询的请求,对于一些仅提供本域名解析功能的服务器来说,会是一个比较安全的做法。

      另外,参与查询的过程中,Windows DNS server有隐含的一个拒绝查询列表,配置在注册表的GlobalQueryBlockList下,所有匹配的名称(不包含domain name),会返回REFUSED响应。默认EnableGlobalQueryBlockList为true。

    • Recursive Query递归查询

      递归查询相对来说比较简单,类似客户端的行为,将请求发送给上游DNS Forwarder,期望收到直接的查询结果。与递归查询相关的配置项如下:

      Windows:
          Recursion配置: 
              dnscmd /config /RecursionRetry
              dnscmd /config /RecursionTimeout
          Forward配置: 
              dnscmd /config /EnableForwarderReordering
              dnscmd /config /ForwardDelegations
              dnscmd /config /ForwardingTimeout
      
      Linux Bind:
          forwarders
          forward (first | only ) 
          first设置优先使用forwarders DNS服务器做域名解析,如果查询不到再使用本地DNS服务器做域名解析。
          only设置只使用forwarders DNS服务器做域名解析,如果查询不到则返回DNS客户端查询失败。
      结合迭代查询,推荐做法是明确DNS服务的目的,例如:
      • 仅供内部解析使用推荐创建root zone,避免内部查询的请求外泄。
      • 内部解析外部,使用专门的DNS服务器做转发(Forwarder)指向迭代查询DNS服务器,同时根据需要考虑是否选择Forwarder first or only等选项,使用专门的DNS服务器做递归查询,避免上级DNS服务异常等问题。
      • 提供互联网客户端获取外部域名解析的DNS服务器上,关注两种情形。一种提供Authoritative Answer,建议也是创建root zone,避免额外的查询服务。一种是类似ISP提供查询转发,需要关注DNS cache缓存的配置。
    • DNS cache配置

      对于DNS缓存来说,最重要的一项就是DNS资源记录(Resource Record)的TTL。影响TTL的因素很多,一般默认在DNS记录创建的时候,我们必须指定对应记录的TTL时间,或者使用对应DNS zone的默认值。当我们配置转发器(Forwarder)时,该服务器作为非权威DNS服务需要关注缓存的配置。Windows DNS server和Linux Bind各自有不同的配置项,具体如下:

      Windows:
          Possitive cache: dnscmd /config /MaxCacheTtl
          Negative cache: dnscmd /config /MaxNegativeCacheTtl
          cache size: dnscmd /config /MaxCacheSize
      
      Linux Bind:
          max-cache-ttl
          max-ncache-ttl
          max-cache-size
          lame-ttl

      注:在配置转发器(Forwarder)的时候,要特别注意缓存时间,因为该服务器所有可以提供解析的记录基本都在缓存中,如果缓存更新不及时、或者造成Lame Delegation,那可能会带来查询异常等问题。例如,在2012之前的Windows DNS server上,默认的DNS Max Cache TTL为172800s,错误的配置可能会带来意外的解析问题。

    • DNS响应

      现今互联网上DNS已经是流量管理的重要手段,智能流量调度等功能最开始是从修改DNS响应开始。通过对DNS响应结果的调整,可以根据地理位置来负载不同地域的客户端访问请求,或者是智能地判断服务器DNS请求的数量来估计负载情况,进而进行负载均衡等操作。基础版的DNS服务也有相关的配置项可供选择:

      Windows:
          Round robin: dnscmd /config /RoundRobin 
          Netmask Ordering: dnscmd /config /LocalNetPriority
          DNS Policies相关内容可参考文后资料了解详情
      
      								(2)
      
      
      
      
      Linux Bind:
          response-policy相关内容可参考文后资料了解详情
      
      								(3)
      
      
      
          rrset-order 
          sortlist

      由于客户端一般总是使用第一个A,因此,调整响应结果的顺序可以从一定程度上达到流量调整的目的。

  • EDNS支持
    Windows:
        dnscmd /config /EnableEDnsProbes
    
    Linux Bind:
        默认bind 9.10以上版本支持Edns0

    EDNS协议按标准来说就是在遵循已有的DNS消息格式的基础上增加一些字段,来支持更多的DNS请求业务。EDNS标准协议最著名的功能是支持超过512字节的udp消息,即Edns0。没有Edns0,DNS使用tcp来完成超过512字节的响应接收。无论是提供解析结果的DNS服务器,还是中间DNS转发器(Forwarder)服务,都推荐关注DNS服务器上是否开启EDNS,以及检查EDNS是否符合规范。

    EDNS(0)的RFC文档 (4) 以及去年国际知名厂商发起的DNS Flag Day活动 (5) 、Client subnet in DNS requests草案 (6) 等相关信息,可参考文后资料了解详情。

  • DNSSEC支持
    Windows:
        dnscmd /config /EnableDnsSec
    
    Linux Bind:
        named.conf配置:
        dnssec-enable yes;
        dnssec-validation yes;
        dnssec-lookaside auto;

    DNSSEC协议在DNS服务上实现,是通过查询NSEC等Resource Record,来验证DNS响应是否经过篡改。如果验证通过,则将解析结果经过正常的DNS Recursive Query Response返回给客户端。目前应该还没有特别多的DNSSEC的需求,但是考虑到已经有一部分国外的网站域名已经开启了DNSSEC,我们可能需要对此进行了解。当然,在发生DNSSEC查询异常的情况下可以考虑在DNS转发器(Forwarder)上禁用DNSSEC来回退到普通递归、迭代查询。

    说明 DNS客户端不参与DNSSEC的验证过程。DNSSEC如何工作可参考文后资料进行参考 (7)

结语

以上就是本期DNS协议与业界实现的全部内容,不过想要透彻地理解各产品,最好的办法是阅读相应的产品文档,可参考文后资料了解详情 (8)(9) ,希望能够对读者有所帮助。

参考资料

(1)DNS RFC:https://www.ietf.org/rfc/rfc1035.txt

(2)Windows DNS Policies Overview:https://docs.microsoft.com/en-us/windows-server/networking/dns/deploy/dns-policies-overview

(3)DNS Response Policy Zones:https://dnsrpz.info/

(4)EDNS(0)的RFC文档:https://tools.ietf.org/html/rfc6891

(5)去年国际知名厂商发起的一个比较著名的活动DNS Flag Day:https://dnsflagday.net/2019/

(6)Client subnet in DNS requests草案:https://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-01

(7)DNSSEC如何工作:https://www.cloudflare.com/dns/dnssec/how-dnssec-works/

(8)Windows产品文档:https://docs.microsoft.com/en-us/windows-server/networking/dns/dns-top

(9)Linux Bind产品文档:https://docs.freebsd.org/doc/8.2-RELEASE/usr/share/doc/bind9/arm/Bv9ARM.html