如何在 Ubuntu 14.04 上将 Bind 配置为缓存或转发 DNS 服务器
介绍
在学习如何配置网站和服务器时,DNS 或域名系统通常是一个很难正确掌握的组件。虽然大多数人可能会选择使用托管公司或域名注册商提供的 DNS 服务器,但创建自己的 DNS 服务器也有一些优势。
在本指南中,我们将讨论如何在 Ubuntu 14.04 机器上安装和配置 Bind9 DNS 服务器作为缓存或转发 DNS 服务器。这两种配置在为机器网络提供服务时都有优势。
先决条件和目标
要完成本指南,您首先需要熟悉一些常见的 DNS 术语。查看本指南以了解我们将在本指南中实施的一些概念。
我们将演示实现类似目标的两个独立配置:缓存和转发 DNS 服务器。
要继续学习,您需要能够访问两台计算机(至少其中一台应该是 Ubuntu 14.04 服务器)。一个将用作客户端,另一个将配置为 DNS 服务器。我们的示例配置的详细信息是:
Role | IP Address |
---|---|
DNS Server | 192.0.2.1 |
Client | 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
无论您希望使用哪种配置选择,实施绑定 DNS 服务器的第一步是安装实际软件。
Bind 软件在 Ubuntu 的默认存储库中可用,所以我们只需要更新我们的本地包索引并使用 apt
安装软件。我们还将包括文档和一些常用实用程序:
sudo apt-get update
sudo apt-get install bind9 bind9utils bind9-doc
现在已经安装了绑定组件,我们可以开始配置服务器了。转发服务器将使用缓存服务器配置作为起点,因此无论您的最终目标如何,首先将服务器配置为缓存服务器。
配置为缓存 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 放大攻击是恶意用户试图关闭 Internet 上的服务器或站点的一种方式。为此,他们试图找到将解析递归查询的公共 DNS 服务器。他们伪造受害者的 IP 地址并发送一个查询,该查询将向 DNS 服务器返回大量响应。这样做时,DNS 服务器会以针对受害者服务器的大量负载来响应一个小请求,从而有效地扩大了攻击者的可用带宽。
托管一个公共的、递归的 DNS 服务器需要大量的特殊配置和管理。为避免您的服务器被用于恶意目的的可能性,我们将配置我们信任的 IP 地址或网络范围列表。
在 options
块上方,我们将创建一个名为 acl
的新块。为您正在配置的 ACL 组创建标签。在本指南中,我们将调用组 goodclients
。
acl goodclients {
};
options {
. . .
在此块中,列出应允许使用此 DNS 服务器的 IP 地址或网络。由于我们的服务器和客户端都在同一个 /24 子网中运行,因此我们将示例限制在该网络中。我们还将添加 localhost
和 localnets
,它们将尝试自动执行此操作:
acl goodclients {
192.0.2.0/24;
localhost;
localnets;
};
options {
. . .
现在我们有了要为其解析请求的客户端 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; # conform to 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; # conform to 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#53
Jun 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; # conform to RFC1035
. . .
完成后保存并关闭文件。您现在应该有一个转发 DNS 服务器。继续下一节以验证您的配置文件并重新启动守护程序。
测试您的配置并重新启动绑定
现在您已将绑定服务器配置为缓存 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 服务器。注释掉所有当前条目并添加指向您的 DNS 服务器的 nameserver
行:
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 0ms
rtt 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 地址(在我们的例子中是 140.211.169.4
)和 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#53
Jun 25 13:16:22 cache named[2004]: error (network unreachable) resolving 'ns4.apnic.com/A/IN': 2001:503:a83e::2:30#53
Jun 25 13:16:23 cache named[2004]: error (network unreachable) resolving 'sns-pb.isc.org/AAAA/IN': 2001:500:f::1#53
Jun 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 服务器或组合这些解决方案。