介绍
DNS,即域名系统,在学习如何配置网站和服务器时,通常是一个难以正确配置的组件。虽然大多数人可能会选择使用由其托管公司或域名注册商提供的DNS服务器,但自己创建DNS服务器也有一些优势。
在本指南中,我们将讨论如何在Ubuntu 14.04机器上安装和配置Bind9 DNS服务器作为缓存或转发DNS服务器。这两种配置在为机器网络提供服务时都有优势。
先决条件和目标
要完成本指南,您首先需要熟悉一些常见的DNS术语。查看本指南以了解我们将在本指南中实施的一些概念。
我们将演示两种实现类似目标的单独配置:缓存和转发DNS服务器。
要跟随操作,您需要访问两台计算机(至少一台应为Ubuntu 14.04服务器)。一台将充当客户端,另一台将配置为DNS服务器。我们示例配置的详细信息如下:
角色 | IP地址 |
---|---|
DNS服务器 | 192.0.2.1 |
客户端 | 192.0.2.100 |
我们将向您展示如何配置客户端机器以使用DNS服务器进行查询。我们将向您展示如何根据您的需求在DNS服务器上配置两种不同的配置。
缓存DNS服务器
第一个配置将是缓存DNS服务器。这种类型的服务器也被称为解析器,因为它处理递归查询,并通常可以处理从其他服务器获取DNS数据的繁重工作。
当缓存DNS服务器找到客户端查询的答案时,它将答案返回给客户端。但它还将在其缓存中存储答案,存储时间由记录的TTL值决定。然后可以将缓存用作后续请求的来源,以加快总往返时间。
您在网络配置中可能拥有的几乎所有DNS服务器都将是缓存DNS服务器。这些服务器弥补了大多数客户机上实现的不足的DNS解析器库。缓存DNS服务器对许多情况都是一个不错的选择。如果您不希望依赖于您的ISP的DNS或其他公共可用的DNS服务器,那么制作自己的缓存服务器是一个不错的选择。如果它与客户机在物理上很近,它也很可能提高DNS查询时间。
转发DNS服务器
我们将演示的第二个配置是转发DNS服务器。从客户端的角度来看,转发DNS服务器看起来几乎与缓存服务器相同,但机制和工作负载是完全不同的。
转发DNS服务器提供了与维护缓存以改善客户端DNS解析时间相同的优势。但它实际上并不执行递归查询。相反,它将所有请求转发到外部解析服务器,然后缓存结果以供以后的查询使用。
这使得转发服务器可以从其缓存中响应,而无需执行所有递归查询的工作。这允许服务器仅进行单个请求(转发的客户端请求),而无需执行整个递归例程。这在外部带宽传输昂贵的环境中可能是一个优势,在这种环境中,您的缓存服务器可能需要经常更改,或者当您希望将本地查询转发到一个服务器,将外部查询转发到另一个服务器时。
在DNS服务器上安装Bind
无论您希望使用哪种配置选择,实施Bind DNS服务器的第一步是安装实际软件。
Bind软件可在Ubuntu的默认存储库中找到,因此我们只需要更新本地软件包索引,并使用apt
安装软件。我们还将包括文档和一些常用实用程序:
sudo apt-get updatesudo apt-get install bind9 bind9utils bind9-doc
现在Bind组件已安装,我们可以开始配置服务器。转发服务器将使用缓存服务器配置作为起点,因此无论您的最终目标是什么,首先将服务器配置为缓存服务器。
配置为缓存DNS服务器
首先,我们将介绍如何配置Bind以充当缓存DNS服务器。此配置将强制服务器在客户端发出查询时递归地寻找其他DNS服务器的答案。这意味着它正在依次查询每个相关的DNS服务器,直到找到整个响应。
默认情况下,Bind配置文件保存在/etc/bind
目录中。现在进入该目录:
cd /etc/bind
我们不会关心该目录中的大多数文件。主配置文件称为named.conf
(named
和bind
是同一应用程序的两个名称)。此文件简单地引用named.conf.options
文件,named.conf.local
文件和named.conf.default-zones
文件。
对于缓存DNS服务器,我们只会修改named.conf.options
文件。使用sudo权限在文本编辑器中打开此文件:
sudo nano named.conf.options
去除注释以提高可读性后,文件如下所示:
options { directory "/var/cache/bind"; dnssec-validation auto; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; };};
要配置缓存,第一步是设置访问控制列表(ACL)。
作为用于解析递归查询的DNS服务器,我们不希望DNS服务器被恶意用户滥用。一种称为DNS放大攻击的攻击尤其麻烦,因为它可能导致您的服务器参与分布式拒绝服务攻击。
DNS放大攻击是恶意用户试图使互联网上的服务器或站点宕机的一种方式。为此,他们尝试找到将解析递归查询的公共DNS服务器。他们伪造受害者的IP地址并发送一个将向DNS服务器返回大型响应的查询。这样一来,DNS服务器会用大负载响应针对受害者服务器的小请求,有效地放大了攻击者的可用带宽。
托管公共递归DNS服务器需要大量特殊配置和管理。为了避免您的服务器被用于恶意目的的可能性,我们将配置一个我们信任的IP地址或网络范围的列表。
在options
块之上,我们将创建一个名为acl
的新块。为您正在配置的ACL组创建一个标签。在本指南中,我们将称该组为goodclients
。
acl goodclients {};
在此块中,列出应允许使用此DNS服务器的IP地址或网络。由于我们的服务器和客户端都在同一个/24子网中运行,我们将将示例限制为此网络。我们还将添加localhost
和localnets
,它们将尝试自动执行此操作:
acl goodclients { 192.0.2.0/24; localhost; localnets;};
现在我们有了一个我们希望解析请求的客户端的ACL,我们可以在options
块中配置这些功能。在此块中,添加以下行:
options { directory "/var/cache/bind"; recursion yes; allow-query { goodclients; }; . . .
我们明确打开了递归,并配置了allow-query
参数以使用我们的ACL规范。我们也可以使用不同的参数,比如allow-recursion
来引用我们的ACL组。如果存在且递归打开,则allow-recursion
将指示可以使用递归服务的客户端列表。
但是,如果未设置allow-recursion
,则Bind将退回到allow-query-cache
列表,然后是allow-query
列表,最后是默认的localnets
和localhost
。由于我们正在配置仅缓存服务器(它没有自己的权威区域,也不转发请求),allow-query
列表将始终仅适用于递归。我们使用它是因为这是指定ACL的最一般方式。
完成这些更改后,保存并关闭文件。
实际上,这就是缓存DNS服务器所需的全部内容。如果您决定使用此服务器类型,请随时跳转到后面了解如何检查配置文件、重新启动服务和实施客户端配置。
否则,请继续阅读,了解如何设置转发DNS服务器。
配置为转发 DNS 服务器
如果转发 DNS 服务器更适合您的基础架构,我们可以轻松地进行设置。
我们将从缓存服务器配置中离开的配置开始。named.conf.options
文件应该如下所示:
acl goodclients { 192.0.2.0/24; localhost; localnets;};options { directory "/var/cache/bind"; recursion yes; allow-query { goodclients; }; dnssec-validation auto; auth-nxdomain no; # 符合 RFC1035 listen-on-v6 { any; };};
我们将使用相同的 ACL 列表来限制我们的 DNS 服务器只能为特定的客户端提供服务。但是,我们需要更改配置,以便服务器不再尝试执行递归查询。
为此,我们不将 recursion
更改为 no。转发服务器仍然通过回答非权威区域的查询来提供递归服务。相反,我们需要设置一个缓存服务器列表,将我们的请求转发到这些服务器。
这将在 options {}
块内完成。首先,我们创建一个名为 forwarders
的块,其中包含我们要转发请求的递归名称服务器的 IP 地址。在我们的指南中,我们将使用 Google 的公共 DNS 服务器(8.8.8.8
和 8.8.4.4
):
. . .options { directory "/var/cache/bind"; recursion yes; allow-query { goodclients; }; forwarders { 8.8.8.8; 8.8.4.4; }; . . .
之后,我们应该将 forward
指令设置为 “only”,因为此服务器将转发所有请求,不应尝试自行解析请求。
完成后,配置文件将如下所示:
acl goodclients { 192.0.2.0/24; localhost; localnets;};options { directory "/var/cache/bind"; recursion yes; allow-query { goodclients; }; forwarders { 8.8.8.8; 8.8.4.4; }; forward only; dnssec-validation auto; auth-nxdomain no; # 符合 RFC1035 listen-on-v6 { any; };};
我们应该做的最后一项更改是 dnssec
参数。根据当前的配置,根据转发的 DNS 服务器的配置,您可能会在日志中看到以下类似的错误:
Jun 25 15:03:29 cache named[2512]: error (chase DS servers) resolving 'in-addr.arpa/DS/IN': 8.8.8.8#53Jun 25 15:03:29 cache named[2512]: error (no valid DS) resolving '111.111.111.111.in-addr.arpa/PTR/IN': 8.8.4.4#53
为了避免这种情况,将 dnssec-validation
设置为 “yes” 并显式启用 dnssec:
. . .forward only;dnssec-enable yes;dnssec-validation yes;auth-nxdomain no; # 符合 RFC1035. . .
完成后保存并关闭文件。现在您应该已经设置了一个转发 DNS 服务器。继续下一节以验证您的配置文件并重新启动守护程序。
测试您的配置并重新启动 Bind
现在您已经将 Bind 服务器配置为缓存 DNS 服务器或转发 DNS 服务器,我们准备实施我们的更改。
在我们在系统上重新启动 Bind 服务器之前,我们应该使用 Bind 提供的工具来检查我们的配置文件的语法。
您可以通过输入以下命令轻松地执行此操作:
sudo named-checkconf
如果您的配置中没有语法错误,shell 提示符将立即返回,而不显示任何输出。
如果您的配置文件中存在语法错误,您将收到有关错误及其发生的行号的警告。如果发生这种情况,请返回并检查文件中的错误。
当您验证配置文件没有任何语法错误时,重新启动 Bind 守护程序以实施更改:
sudo service bind9 restart
之后,当您设置客户端机器时,请在服务器上监视服务器日志,以确保一切顺利。在服务器上保持此运行:
sudo tail -f /var/log/syslog
现在,打开一个新的终端窗口来配置您的客户端机器。
配置客户端机器
现在您的服务器已经运行起来,您可以配置客户端机器以使用此 DNS 服务器进行查询。
登录到您的客户端机器。确保您使用的客户端已在您为 DNS 服务器设置的 ACL 组中指定。否则,DNS 服务器将拒绝为客户端提供服务。
我们需要编辑 /etc/resolv.conf
文件,将我们的服务器指向名称服务器。在这里所做的更改将只持续到重新启动,这对于测试来说非常好。如果我们对测试结果满意,我们可以使这些更改永久生效。
使用具有 sudo 权限的文本编辑器打开文件:
sudo nano /etc/resolv.conf
该文件将通过设置 nameserver
指令列出要用于解析查询的 DNS 服务器。注释掉所有当前条目,并添加一个 nameserver
行,将其指向您的 DNS 服务器:
nameserver 192.0.2.1# nameserver 8.8.4.4# nameserver 8.8.8.8# nameserver 209.244.0.3
保存并关闭文件。
现在,您可以使用一些常见的工具来测试查询是否可以正确解析。
您可以使用 ping
来测试是否可以连接到域:
ping -c 1 google.com
PING google.com (173.194.33.1) 56(84) bytes of data.64 bytes from sea09s01-in-f1.1e100.net (173.194.33.1): icmp_seq=1 ttl=55 time=63.8 ms--- google.com ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 63.807/63.807/63.807/0.000 ms
这意味着我们的客户端可以使用我们的 DNS 服务器连接到 google.com
。
您可以使用 dig
等专用于 DNS 的工具来获取更详细的信息。这次尝试不同的域:
dig linuxfoundation.org
; <<>> DiG 9.9.5-3-Ubuntu <<>> linuxfoundation.org;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35417;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;linuxfoundation.org. IN A;; ANSWER SECTION:linuxfoundation.org. 6017 IN A 140.211.169.4;; Query time: 36 msec;; SERVER: 192.0.2.1#53(192.0.2.1);; WHEN: Wed Jun 25 15:45:57 EDT 2014;; MSG SIZE rcvd: 64
您可以看到查询花费了 36 毫秒。如果我们再次发出请求,服务器应该从其缓存中获取数据,从而减少响应时间:
dig linuxfoundation.org
; <<>> DiG 9.9.5-3-Ubuntu <<>> linuxfoundation.org;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18275;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;linuxfoundation.org. IN A;; ANSWER SECTION:linuxfoundation.org. 6012 IN A 140.211.169.4;; Query time: 1 msec;; SERVER: 192.0.2.1#53(192.0.2.1);; WHEN: Wed Jun 25 15:46:02 EDT 2014;; MSG SIZE rcvd: 64
如您所见,缓存的响应速度明显更快。
我们还可以使用 IP 地址进行反向查找,使用 dig 的 -x
选项:
dig -x 140.211.169.4
; <<>> DiG 9.9.5-3-Ubuntu <<>> -x 140.211.169.4;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61516;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;4.169.211.140.in-addr.arpa. IN PTR;; ANSWER SECTION:4.169.211.140.in-addr.arpa. 3402 IN CNAME 4.0-63.169.211.140.in-addr.arpa.4.0-63.169.211.140.in-addr.arpa. 998 IN PTR load1a.linux-foundation.org.;; Query time: 31 msec;; SERVER: 192.0.2.1#53(192.0.2.1);; WHEN: Wed Jun 25 15:51:23 EDT 2014;; MSG SIZE rcvd: 117
如您所见,反向查找也成功了。
回到您的 DNS 服务器,您应该查看在测试期间是否记录了任何错误。可能出现的一个常见错误如下所示:
. . .Jun 25 13:16:22 cache named[2004]: error (network unreachable) resolving 'ns4.apnic.net/A/IN': 2001:dc0:4001:1:0:1836:0:140#53Jun 25 13:16:22 cache named[2004]: error (network unreachable) resolving 'ns4.apnic.com/A/IN': 2001:503:a83e::2:30#53Jun 25 13:16:23 cache named[2004]: error (network unreachable) resolving 'sns-pb.isc.org/AAAA/IN': 2001:500:f::1#53Jun 25 13:16:23 cache named[2004]: error (network unreachable) resolving 'ns3.nic.fr/A/IN': 2a00:d78:0:102:193:176:144:22#53
这些指示服务器正在尝试解析 IPv6 信息,但服务器未配置为使用 IPv6。您可以通过告知 Bind 仅使用 IPv4 来解决此问题。
为此,使用具有 sudo 权限的文本编辑器打开 /etc/default/bind9
文件:
sudo nano /etc/default/bind9
在其中,修改 OPTIONS
参数以包含 -4
标志,以强制仅使用 IPv4:
OPTIONS="-u bind -4"
保存并关闭文件。
重新启动服务器:
sudo service bind9 restart
您将不会再在日志中看到这些错误。
使客户端 DNS 设置永久生效
如前所述,将客户端机器指向我们的 DNS 服务器的 /etc/resolv.conf
设置在重启后将不会保留。为了使更改持久化,我们需要修改用于生成此文件的文件。
如果客户端机器正在运行 Debian 或 Ubuntu,请使用 sudo 权限打开 /etc/network/interfaces
文件:
sudo nano /etc/network/interfaces
查找 dns-nameservers
参数。您可以删除现有条目并用您的 DNS 服务器替换它们,或者只需将您的 DNS 服务器添加为选项之一:
. . .iface eth0 inet static address 111.111.111.111 netmask 255.255.255.0 gateway 111.111.0.1 dns-nameservers 192.0.2.1. . .
完成后保存并关闭文件。下次启动时,您的设置将被应用。
如果客户端正在运行 CentOS 或 Fedora,则需要打开 /etc/sysconfig/network/network-scripts/ifcfg-eth0
文件:
sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
在文件中查找以 DNS
开头的行。将 DNS1
更改为您的 DNS 服务器。如果您不希望使用其他 DNS 服务器作为备用,可以删除其他条目:
DNS1=192.0.2.1
完成后保存并关闭文件。下次启动时,您的客户端应该使用这些设置。
结论
您现在应该配置了一个用于为客户端提供缓存或转发 DNS 服务器。这可以是加快您正在管理的机器的 DNS 查询速度的好方法。
如果您想创建一个为您自己的域区域授权的 DNS 服务器,您可以配置一个仅授权的 DNS 服务器或结合这些解决方案。