各种DNS技术对比

在开源界,有多种DNS技术。在RHEL上,笔者主要用过三种:BIND、Unbound(DNS缓存)、Dnsmasq等。

各种DNS技术功能对比如下:

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java

各种DNS适用的操作系统平台如下:

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_02

从上图我们可以看出来:在三种DNS技术中,Bind的功能最全、适用的操作系统种类最多,也是RHEL标准带的DNS服务。

 

下面对这三种DNS技术进行简单介绍。

 

BIND是事实上的标准DNS服务器。它是一种免费软件产品,在大多数Unix和Linux平台上均已分发,在大多数情况下也被称为named(名称守护程序)。它是部署最广泛的DNS服务器。[1]从历史上看,BIND经历了三个主要修订,每个修订的体系结构都有明显不同:BIND4,BIND8和BIND9。BIND4和BIND8现在在技术上已过时,因此本文中不予考虑。BIND9是对BIND的完全重写,除其他功能和增强功能外,还具有完整的DNSSEC支持。RHEL8自带的是BIND9.11。

 

Unbound是一种为高性能而设计的验证,递归和缓存DNS服务器。它是由NLnet Labs根据BSD许可在2008年5月20日发行的免费软件(版本1.0.0)。从版本10.0开始,它作为基本系统的一部分安装在FreeBSD中;从版本8.0开始,它被安装在NetBSD中。OpenBSD 5.6及更高版本中也提供了一个版本。(BIND随附的FreeBSD的早期版本。)

 

Dnsmasq是一种轻量级,易于配置的DNS转发器,旨在为小型网络提供DNS(以及可选的DHCP和TFTP)服务。它可以服务不在全局DNS中的本地计算机的名称。Dnsmasq接受DNS查询,并从一个小的本地缓存中答复它们,或将其转发到真实的递归DNS服务器。它加载/etc/hosts的内容,以便可以解析未出现在全局DNS中的本地主机名。RHEL8中的dnsmasq开始支持DNSSEC(符合上面功能对照表的描述)

 

在RHEL7中,官方配置是BIND。RHEL8默认也使用BIND。Dnsmasq的好处是配置简单,使用方便。这在小型的开发测试环境和PoC环境非常适合。Unbound主要功能是做DNS缓存。

 



DNS的概念

 

域名系统 (DNS) 是一个层次命名系统,充当联网主机和资源的目录。目录中的信息将网络名称映射到数据,并且在称为资源记录的逻辑条目中维护。DNS 层次结构从顶层的 root 域“.”开头,再划分为多个下级域。

DNS 层次结构的每个级别在域名中以“.”描述,“." 为最高级别。comnet 和 org 之类的域占据层次结构的第二级,example.com 和 redhat.com 之类的域占据第三级,以此类推。

使用 DNS 时,务必分清楚一些用于指示 DNS 层次结构的常见术语,如 domainsubdomain 和 zone

domain 是资源记录的集合,这些资源记录以公用名称结尾并且表示 DNS 名称空间的整个子树,如 example.com。最大可能的域是 root 域,即 “.”,它包括整个 DNS 命名空间。

顶级域 (TLD) 是仅有一个组成部分的域。通用 TLD (gTLD) 最初按主题组织,并包括 .com.edu 和 .net 等等。国家/地区代码 TLD (ccTLD) 根据国家来组织,并且包括 .us.uk.cn 和 .ru 等等。

子域

subdomain 是指作为另一个域的子树的域。在讨论两个域之间的相互关系时使用该术语。例如,lab.example.com 是 example.com 的子域。

区域

zone 是指特定名称服务器直接负责或对其具有权威的某个域的组成部分。这可以是整个域,或者只是域的一部分(其部分或所有子域被委派给其他名称服务器)。



DNS查询分析

系统需要使用 DNS 服务器执行名称解析时,它将首先向 /etc/resolv.conf 中列出的服务器依次发送查询,直到它获得响应或查询了全部列出的服务器。host 或 dig 命令可用于手动查询 DNS 名称。

本地权威数据

当查询到达 DNS 服务器时,服务器首先确定正在查询的信息是否驻留在服务器对其有权威的区域中。如果服务器是所查询名称或地址所属区域的权威,那么服务器将以其本地区域文件中包含的信息来响应客户端。这种类型的响应称为权威答案 (aa),因为提供响应的服务器对提供的数据有权威。来自名称服务器的权威答案在 DNS 响应的标题中开启了 aa 标志。

本地的缓存非权威数据

如果 DNS 服务器不是相关记录的权威,但是最近又获取了该记录以回答之前的查询,那么它仍可能在其缓存中具有一份记录副本。缓存是用于在指定时间内存储查询答案的位置,这一时间是由每个资源记录响应中称为生存时间 (TTL) 的值来确定的。如果服务器的缓存中存在答案,则会将该答案提供给客户端。此答案将不会设置 aa 标志,因为服务器对提供的数据没有权威。

通过递归获取的远程非权威数据

如果 DNS 服务器对于正在查询的名称没有权威,则 DNS 服务器不会在其缓存中占有记录,DNS 服务器随后将尝试通过称为递归的迭代过程来检索记录。具有空缓存的 DNS 服务器将按照从其本地预填充根 hints 文件中检索的 IP 地址查询其中一个根名称服务器,从而开始递归过程。根名称服务器随后可能将以引用响应,这表明名称服务器对于包含所查询名称的 TLD 具有权威。

在收到引用后,DNS 服务器随后将对作为引用的 TLD 权威名称服务器执行另一个迭代查询。根据正在查询的名称中是否有更多剩余委派,该权威名称服务器将发送权威答案或者另一个引用。此操作将继续,直到到达权威服务器且权威服务器使用权威答案做出响应。

最终答案以及在最终答案之前获取的所有中间答案都将由 DNS 服务器进行缓存以提高性能。如果在查询 www.example.com 期间,DNS 服务器发现 example.com 区域具有权威名称服务器,则它将针对任何将来查询直接查询这些服务器以获取 example.com 区域中的信息,而不是在根名称服务器中重新启动递归。



DNS资源记录

 

DNS 资源记录 (RR) 是 DNS 区域中的条目,用于指定有关该区域中某个特定名称或对象的信息。一个资源记录包含以下元素:typeTTLclass 和 data,并且按以下格式组织:

owner-name           TTL      class      type     data
www.example.com.     300      IN         A        192.168.1.10

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_03

有几个重要的资源记录类型:

A(IPv4 地址)记录

A 资源记录将主机名映射到 IPv4 地址。

[student@serverX ~]$ host -v -t A example.com
Trying "example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22681
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; QUESTION SECTION:
;example.com. IN A

;; ANSWER SECTION:
example.com. 86400 IN A 172.25.254.254

Recieved 96 bytes from 172.25.254.254#53 in 1 ms

AAAA(IPv6 地址)记录

AAAA 资源记录(“四 A”记录)将主机名映射到 IPv6 地址。

[student@serverX ~]$ host -v -t AAAA a.root-servers.net
Trying "a.root-servers.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18194
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 12

;; QUESTION SECTION:
;a.root-servers.net. IN AAAA

;; ANSWER SECTION:
a.root-servers.net. 604800 IN AAAA 2001:503:ba3e::2:30

Received 64 bytes from 172.25.254.254#53 in 78 ms

CNAME(规范名称)记录

CNAME 资源记录将一个记录别名化为另一个记录(规范名称),其中应具有 A 或 AAAA 记录。

当 DNS 解析器收到 CNAME 记录作为查询的响应时,DNS 解析器将使用规范名称(而非原始名称)重新发出查询。

CNAME 记录的数据字段可以指向 DNS 中任何位置的名称,无论是区域内部还是区域外部:

www-dev.example.com. IN CNAME lab.example.com.
www.example.com.     IN CNAME www.redhat.com.

CNAME 记录很有用,但在使用时应小心。通常,出于效率和脆弱性的原因,应避免将 CNAME 记录指向其他 CNAME 记录,从而也可以避免意外创建 CNAME 循环。CNAME 记录链必须以 A 和/或 AAAA 记录结束。请注意,当使用内容传输网络 (CDN) 提高通过 Internet 传输数据的速度和可靠性时,可以合法使用 CNAME 链。同样地,NS 和 MX 记录不得指向 CNAME 记录,而是指向名称包含 A 和/或 AAAA 记录的名称。

[student@serverX ~]$ host -v -t A ipa-ca.server0.example.com
Trying "ipa-ca.server0.example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11931
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 2

;; QUESTION SECTION:
;ipa-ca.server0.example.com. IN A

;; ANSWER SECTION:
ipa-ca.server0.example.com. 86400 IN CNAME server0.example.com.
server0.example.com. 86400 IN A 172.25.0.11

Recieved 125 bytes from 172.25.254.254#53 in 1 ms

PTR(指针)记录

PTR 记录将 IPv4 或 IPv6 地址映射到主机名。它们用于反向 DNS 解析

PTR 记录以特殊格式对行为类似于主机名的 IP 地址进行编码。对于 IPv4 地址,地址被逆向,最具体的部分在最前面,并且结果被视为特殊域 in-addr.arpa 的子域中的主机。对于 IPv6 地址,地址分割为半字节边界上的子域(每个十六进制数),并且设置为特殊域 ip6.arpa 的子域,如以下示例中所示。尽管此语法可能看上去很奇怪,但这更便于 DNS 管理员将地址范围的职责委派给其他 DNS 管理员。

[student@serverX ~]$ host -v -t PTR 172.25.0.10
Trying "10.0.25.172.in-addr.arpa"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36389
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; QUESTION SECTION:
;10.0.25.172.in-addr.arpa. IN PTR

;; ANSWER SECTION:
10.0.25.172.in-addr.arpa. 86400 IN PTR desktop0.example.com.

Received 127 bytes from 172.25.254.254#53 in 2 ms
[student@serverX ~]$ host -v -t PTR 2001:503:ba3e::2:30
Trying "0.3.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.e.3.a.b.3.0.5.0.1.0.0.2.ip6.arpa"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32138
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;0.3.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.e.3.a.b.3.0.5.0.1.0.0.2.ip6.arpa. IN PTR

;; ANSWER SECTION:
0.3.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.e.3.a.b.3.0.5.0.1.0.0.2.ip6.arpa. 86400 IN PTR a.root-servers.net.

Received 122 bytes from 172.25.254.254#53 in 174 ms

NS(名称服务器)记录

NS 记录将域名映射到 DNS 名称服务器,而后者对其 DNS 区域具有权威。

区域的每个公开权威名称服务器必须具有 NS 记录。

[student@serverX ~]$ host -v -t NS example.com
Trying "example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29362
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; QUESTION SECTION:
;example.com. IN NS

;; ANSWER SECTION:
example.com. 86400 IN NS classroom.example.com.

Received 80 bytes from 172.25.254.254#53 in 0 ms

SOA(授权起始)记录

SOA 记录提供了有关 DNS 区域工作方式的信息。

每个区域正好有一个 SOA 记录。其指定区域的哪个名称服务器是主要名称服务器()、有关次要()名称服务器应如何更新其信息副本的信息以及区域的管理联系方式。其数据字段包含以下元素:

 

[student@serverX ~]$ host -v -t SOA example.com
Trying "example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58434
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;example.com. IN SOA

;; ANSWER SECTION:
example.com. 86400 IN SOA classroom.example.com. root.classroom.example.com. 2013091600 3600 300 604800 60

Received 121 bytes from 172.25.254.254#53 in 0 ms

MX(邮件交换)记录

MX 记录将域名映射到邮件交换,后者将接受该名称的电子邮件。

此记录类型的数据是一个优先级编号(最低优先级)(用于确定在多个 MX 记录之间进行选取时的顺序)以及一个用于该名称的邮件交换的主机名。

[student@serverX ~]$ host -v -t MX example.com
Trying "example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47187
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; QUESTION SECTION:
;example.com. IN MX

;; ANSWER SECTION:
example.com. 86400 IN MX 10 classroom.example.com.

Received 96 bytes from 172.25.254.254#53 in 0 ms

TXT(文本)记录

TXT 记录用于将名称映射到任何人类可读的文本。

TXT 记录通常用于提供由发送方策略框架 (SPF)域密钥识别邮件 (DKIM)基于域的消息身份验证、报告和一致性 (DMARC) 等等使用的数据。

[student@serverX ~]$ host -v -t TXT lwn.net
Trying "lwn.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41137
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;lwn.net. IN TXT

;; ANSWER SECTION:
lwn.net. 28619 IN TXT "v=spf1 ip4:72.51.34.34 ip4:70.33.254.29 -all"

Received 638 bytes from 192.168.2.11#53 in 74 ms

SRV(服务)记录

SRV 记录用于查找支持域的特定服务的主机。

使用格式设置为包含服务和协议名称的域名,如 _service._protocol.domainnameSRV 记录可提供为域提供服务的主机的名称以及服务侦听的端口号。SRV 记录还包括 priority 和 weight 值,以指示在多个主机可用于某一特定服务时应该使用主机的顺序。

此 SRV 记录示例表明,server0.example.com 域在主机 server0.example.com 上的端口 389 使用 TCP 来提供 LDAP 服务,且优先级为 0,权重为 100

[student@serverX ~]$ host -v -t SRV _ldap._tcp.server0.example.com
Trying "_ldap._tcp.server0.example.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35665
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3

;; QUESTION SECTION:
;_ldap._tcp.server0.example.com. IN SRV

;; ANSWER SECTION:
_ldap._tcp.server0.example.com. 86400 IN SRV 0 100 389 server0.example.com.

Received 154 bytes from 172.25.254.254#53 in 0 ms

主机和资源记录

一个典型主机,无论是客户端还是服务器,都将具有以下记录:

  • 一个或多个 A 和/或 AAAA 记录,用于将其主机名映射到其 IP 地址

  • 其每个 IP 地址有一个 PTR 记录,用于将 IP 地址逆向映射到其主机名

  • (可选)一个或多个 CNAME 记录,用于将备用名称映射到其规范主机名

除了区域中主机的记录之外,DNS 区域通常还具有以下内容:

  • 正好一个 SOA 记录,用于指定区域的工作方式

  • 其每个权威名称服务器的 NS 记录

  • 一个或多个 MX 记录,用于将域名映射到邮件交换,后者接收以域名结尾的地址的电子邮件。

  • (可选)各种功能(如 SPF 或 Google 地点验证)的一个或多个 TXT 记录

  • (可选)用于在域中查找服务的一个或多个 SRV 记录

 



配置DNS缓存服务器

 

缓存DNS在本地缓存中存储 DNS 查询结果,并且在 TTL 到期后从缓存中删除资源记录。通常设置缓存名称服务器以代表本地网络上的客户端执行查询。这降低了 Internet 上的 DNS 流量,从而极大提高了 DNS 名称解析的效率。随着缓存的增加,缓存名称服务器从其本地缓存中回答越来越多的客户端查询,从而提高 DNS 性能。

DNSSEC 验证

鉴于 UDP 的无状态性质,DNS 事务很容易被欺骗和篡改。缓存名称服务器过去一直是期望重定向或劫持网络流量的攻击者青睐的目标。这通常通过以下方式来实现:利用 DNS 服务器软件中的漏洞来欺骗 DNS 服务器接受恶意数据并将其填充到其缓存中,也就是通常称为缓存中毒的方法。一旦攻击者成功使 DNS 服务器的缓存中毒,便可利用 DNS 服务器上的缓存名称服务有效破坏众多客户端收到的 DNS 数据,并因此可以重定向或劫持客户端的网络流量。

缓存名称服务器可以极大提高本地网络上的 DNS 性能,同时它们还可以通过执行域名系统安全性扩展 (DNSSEC) 验证来提高安全性。在缓存名称服务器上启用的 DNSSEC 验证可在将资源记录置于缓存中供客户端使用之前验证资源记录的真实性和完整性,从而防止客户端遭受缓存中毒。


作为 root 用户安装 
unbound 软件包。

yum install -y unbound

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_04

[root@localhost ~]# systemctl start unbound.service

[root@localhost ~]# systemctl enable unbound.service

 

默认情况下,unbound 仅侦听 localhost 网络接口。要使 unbound 能够作为缓存名称服务器供远程客户端使用,请使用 /etc/unbound/unbound.conf 的 server 子句中的 interface 选项来指定要侦听的网络接口。值 0.0.0.0 会将 unbound 配置为侦听所有网络接口:

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_05

 

默认情况下,unbound 会拒绝来自所有客户端的递归查询。在 /etc/unbound/unbound.conf 的 server 子句中,使用 access-control 选项指定允许哪些客户端进行递归查询。

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_06

在 /etc/unbound/unbound.conf 中,创建 forward-zone 子句以指定要将查询转发到的 DNS 服务器。可以使用 forward-host 选项按主机名指定 DNS 服务器,或者使用 forward-addr 选项按 IP 地址指定。对于缓存名称服务器,通过将 forward-zone 指定为“.”以转发所有查询。这里指向的DNS服务器,需要指定上一级DNS服务器(因为是要加快DNS查询,所以缓存上一级DNS的查询内容)。

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_07

 

/etc/unbound/unbound.conf的服务器子句中的domain-insecure选项可以使用指定应跳过DNSSEC验证的域。这 在处理未签名的内部域时通常是需要的,否则会导致信任链验证失败。

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_08

如果需要,请安装特定签名区域的信任定位符(不含完整信任链)。

由于并非所有 ccTLD 都实现了 DNSSEC,这些 ccTLD 的子域可以由 DNSSEC 签名,但是仍具有损坏的信任链。可以使用 /etc/unbound/unbound.conf 的 server 子句中的 trust-anchor 选项指定区域的信任定位符,从而解决此问题。使用 dig 来获取区域的密钥签名密钥 (KSK) 的 DNSKEY 记录,并输入该记录作为 trust-anchor 选项的值。

dig +dnssec DNSKEY example.com

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_09

 

检查 /etc/unbound/unbound.conf 配置文件是否有语法错误。这点很重要,必须保证没有错误。

# unbound-checkconf

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_10

重新启动 unbound.service,配置防火墙以允许 DNS 流量。

 

[root@localhost ~]#  systemctl restart unbound.service

[root@localhost ~]# firewall-cmd --permanent --add-service=dns

success

[root@localhost ~]# firewall-cmd --reload

success

 

对 DNS 问题进行故障排除时,缓存名称服务器的管理员需要转储缓存数据,如由于陈旧资源记录产生的缓存数据。通过 unbound DNS 服务器,可以通过联合 dump_cache 子命令运行 unbound-control 实用程序来转储缓存。

unbound-control dump_cache

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_11

使用 dump_cache 命令执行 unbound-control 以便以文本格式将缓存转储到 stdout。可以将此输出定向到文件以进行存储,也可以在之后使用 unbound-control load_cache 命令重新加载到缓存中(如果需要)。unbound-control load_cache 从 stdin 中读取以填充缓存。

举个例子:

各种DNS的技术对比以及DNS缓存配置 : RHEL8学习系列5_java_12

[root@repo ~]# unbound-control load_cache <123

ok

 

清空 unbound 缓存

缓存名称服务器的管理员还需要经常从缓存中清除过期的资源记录。在过期资源记录上的 TTL 到期之前,缓存中的错误和过期资源记录将阻止新的已更正的对应资源记录供客户端使用。管理员可以通过执行带有 flush 子命令的 unbound-control 来强制清除过期记录,而不必等待 TTL 过期。

#unbound-control flush www.example.com

如果需要从 unbound DNS 服务器的缓存中清除属于某个域的所有资源记录,则可以使用 flush_zone 子命令来执行 unbound-control

[root@serverX ~]# unbound-control flush_zone example.com
ok removed 3 rrsets, 1 messages and 0 key entries

使用 dnssec-trigger 更新本地缓存 unbound 配置

除了为本地子网提供缓存名称服务,unbound 作为本地缓存名称服务器也很有用,可提供安全的 DNS 名称解析以供在个别系统上本地使用。对于本地缓存名称服务器设置,/etc/resolv.conf 中的 nameserver 条目将配置为指向 unbound 正在侦听的本地主机(这个上面步骤指定为上一级DNS Server不同)。unbound 配置将 DNS 请求转发到上游名称服务器并验证其响应。