在本系列文章的前一篇DNS(域名系统)简介中,我描述了 DNS 数据库的结构以及如何在客户端上配置名称服务。我还列出并描述了一些在构建名称服务器或尝试解释 dig 命令结果时可能遇到的更常见的 DNS 记录。
在本文中,我将向您展示如何使用 BIND(伯克利互联网名称域)构建您自己的名称服务器。它并不像您想象的那么困难,尤其因为您可以分两个阶段完成。
在本文中,您将首先学习如何创建缓存名称服务器,然后您将继续学习如何将其升级为完整的、用于您网络的(主)域名服务器,并配有正向和反向区域文件。
使用 BIND 设置 DNS 服务器
使用 BIND 设置名称服务器非常简单,因此我将向您展示如何在您可能拥有的任何计算机上进行设置以进行实验。这个小型的实验室项目将向您展示如何在您的计算机上安装和配置 BIND 作为缓存名称服务器、对其进行测试,然后将其设置为具有区域文件的主名称服务器,您可以将该区域文件用作您网络的名称解析器,或者仅用于测试。
在您拥有的任何 GNU/Linux 计算机上设置名称服务器在技术上是可行的,因为它不会干扰网络上的其他主机或其运行。但是,您可能不应在您不拥有或无权修改的计算机上执行此操作,除非您已获得明确许可。
我的设置
您只需要一台计算机即可执行此实验室项目中的所有任务,但一项任务除外。我在功能更强大的 ThinkPad 上使用此设置,因为当我使用有线或无线连接连接到非家庭网络时,DHCP(动态主机配置协议)提供的名称服务器有时可能不可靠。为了表明几乎任何主机都可以很好地充当名称服务器,我已经在旧的 ASUS EeePC 900 上网本上测试了这个项目。
我将在此项目中使用我的 ASUS 的私有 IP 地址,但您应该使用您正在使用的主机的 IP 地址。
hosts 文件
首先,让我们看一下 /etc/hosts 文件。在其默认状态下,hosts 文件中应该只有两行,即下面列表 1 中看到的前两行。
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# Lab hosts
192.168.25.1 server
192.168.25.21 host1
192.168.25.22 host2
192.168.25.23 host3
192.168.25.24 host4
列表 1:您可以维护一个简单的 hosts 文件,以在小型网络中执行解析器的功能。
虽然您可以像列表 1 中所示的那样添加主机名及其各自的 IP 地址,但这并不是名称服务的最佳解决方案,尤其是在旅行时。如果您的 hosts 文件中有其他条目,如果它们干扰命名或 IP 地址,您可能需要在此项目期间将它们注释掉。你们大多数人除了两个默认行之外不会有任何其他条目。
准备工作
缓存名称服务器无法取代您使用 /etc/hosts 来解析内部网络上的主机名;但是,与使用 ISP 或其他公共名称服务器相比,缓存名称服务器可以在解析常用外部名称(例如 www.cnn.com)时提高性能。最好的部分是设置缓存名称服务器非常容易。
在开始之前,您应该执行以下步骤进行准备。
首先,制作文件 /etc/hosts、/etc/named.conf、resolv.conf 和 /etc/sysconfig/iptables 的备份副本。
如果尚未安装,请使用您的发行版的软件包管理器安装以下 BIND RPM:bind、bind-chroot 和 bind-utils。要使您的实验室主机能够使用缓存名称服务器,您必须在 /etc/resolv.conf 中添加一个名称服务器行,以指向您自己的主机。例如,如果您的实验室主机 IP 地址是 192.168.0.203,就像我的 epc 一样,请将以下行添加到 /etc/resolv.conf 中的名称服务器列表的顶部
name server 192.168.0.203
请务必使用您正在进行此项目的主机的 IP 地址。
您可以使用本地主机的 IP 地址 127.0.0.1 而不是外部 IP 地址。您还应该注释掉指向其他主机作为名称服务器的任何行。请务必保存修改后的 resolv.conf 文件。
这些更改将立即生效,无需重启或服务重启。现在尝试 ping 一个不阻止 ICMP(互联网控制消息协议)数据包的常见公共主机;请随意使用我的防火墙,它是一个 Raspberry Pi。
ping wally2.both.org
您应该会收到“未知主机”或“名称或服务未知”错误,因为您当前在 resolv.conf 文件中没有定义任何工作 DNS 服务或解析器。现在使用 dig 命令查看名称服务是否正在工作。
dig wally2.both.com
您应该会收到错误“连接超时;无法连接到任何服务器。”
设置缓存名称服务器
缓存名称服务器不是任何域的权威来源。它只是缓存来自其服务的网络的所有名称解析器请求的结果,以加快对将来对同一远程主机的请求的响应。
注意:named.conf 文件对语法,尤其是标点符号非常挑剔。分号用于分隔条目的结尾和节的结尾以及行的结尾。请务必按照示例所示正确添加它们。
对于缓存名称服务器的初始设置,需要对默认的 /etc/named.conf 文件进行一些修改,因此请使用您喜欢的编辑器编辑该文件。首先,将您的本地测试主机的 IP 地址添加到“listen-on port 53”行,如下面的列表 2 所示。这使 named 能够侦听您主机的外部 IP 地址,以便其他计算机也可以将其用作名称服务器。
默认情况下,BIND 引用互联网的根名称服务器来查找域的权威名称服务器。可以指定其他称为“转发器”的服务器,本地 BIND 实例会将请求发送到这些服务器,而不是根服务器。这确实增加了 DNS 劫持的可能性。
添加如下所示的“forwarders”行。这告诉您的缓存 DNS 服务器在本地尚未缓存 IP 地址时从哪里获取 IP 地址。下面列表中的 IP 地址是 Google 公共 DNS 服务器 的地址。您可以使用您的本地 ISP 或 OpenDNS 或其他一些公共名称服务器作为您的转发器。没有必要定义任何转发器,在这种情况下,BIND 将使用 /var/named/named.ca 文件中定义的互联网根服务器来查找域的权威名称服务器(如果未定义转发器)。但对于本练习,请按照我在列表 2 中所做的定义转发器。
注释掉 IPV6 行,因为我们在实验室环境中不使用 IPV6。请注意,“//”两个正斜杠在 named.conf 文件中表示注释。
//
// named.conf
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only name server (as a localhost DNS resolver only).
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
//
options {
listen-on port 53 { 127.0.0.1; 192.168.0.203; };
// listen-on-v6 port 53 { ::1; };
forwarders { 8.8.8.8; 8.8.4.4; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-query { localhost; 192.168.0.0/24; };
recursion yes;
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";
managed-keys-directory "/var/named/dynamic";
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
列表 2:/etc/named.conf 文件提供了设置缓存名称服务器所需的简单配置。需要添加或更改的行以粗体突出显示。
将本地网络地址 192.168.0.0/24 添加到 allow-query 行。此行指定此 DNS 服务器将接受 DNS 查询的网络。
启动名称服务
现在启动 named 服务,并将 named 服务配置为在每次启动时启动。我在我的 Fedora 主机上使用 systemctl 命令,但根据您使用的发行版,该命令可能有所不同。请注意,BIND 解析器服务的名称是 named。
systemctl enable named
systemctl start named
您可以执行的第一个测试以确保您的缓存名称服务器正在工作是使用 dig 查找 wally2.both.org 的 DNS 数据库信息。为了进一步测试您的缓存名称服务器,请使用 dig 命令获取一些常见互联网网站(例如 www.opensource.com、CNN、Wired 以及您喜欢的任何其他网站)的 IP 地址。结果现在应该显示您的主机作为响应服务器。
此时,您的缓存名称服务器将正确解析互联网上的主机,这是因为对公共主机的 DNS 请求被转发到 Google 公共名称服务器——请参阅 named.conf 中的“forwarders”行。但是,您仍然依赖 /etc/hosts 文件进行内部名称服务。创建主名称服务器可以解决该问题。
创建主名称服务器
一旦您创建了缓存名称服务器,将其转换为成熟的主名称服务器并不太困难。主名称服务器是它所代表的域的权威来源。
您需要再次更改 named.conf 并创建几个新文件。您将创建一个名为 Example.com 的域,这是一个在本文档之类的文档中为示例目的保留的域名。Example.com 域在互联网上确实有一个 IP 地址和一个非常稀疏的网站,但您可以在实验室项目的其余部分中使用该名称,而不会给任何人造成问题。在本练习的其余部分,您将使用 Example.com 域作为内部域名。
您将创建的两个新文件是正向和反向区域文件,您将它们放在 /var/named 目录中。此位置由 named.conf 配置文件中的“directory”指令指定。
创建正向区域文件
正向区域文件包含“A”记录,这些记录将区域(也称为域)中的主机名称与其各自的 IP 地址配对。它也可能包含 CNAME 记录(它是 A 记录中真实主机名的别名)和用于邮件服务器的 MX 记录。
创建一个基本的正向区域文件 /var/named/example.com.zone,并将以下行添加到其中。完成时,您的区域文件应如下面的列表 3 中的示例区域文件所示。
; Authoritative data for example.com zone
;
$TTL 1D
@ IN SOA epc.example.com root.epc.example.com. (
2017031301 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
$ORIGIN example.com.
example.com. IN NS epc.example.com.
epc IN A 127.0.0.1
server IN A 192.168.25.1
www IN CNAME server
mail IN CNAME server
test1 IN A 192.168.25.21
t1 IN CNAME test1
test2 IN A 192.168.25.22
test3 IN A 192.168.25.23
test4 IN A 192.168.25.24
; Mail server MX record
example.com. IN MX 10 mail.example.com.
列表 3:Example.com 域的正向区域文件包含此域的主机名及其 IP 地址。
列表 3 中的第一个非注释行是生存时间说明符,在这种情况下,对于所有未另行指定的记录,生存时间为一天。D 代表天。SOA(授权起始)行中的说明符同样显而易见。有关 SOA 记录中参数的详细信息,请参阅 此处。
NS 记录必须具有您正在执行此实验室项目的主机的 FQDN(完全限定域名)。文件中还必须有一个 A 记录,其中包含主机的有效 IP 地址。在这种情况下,您应该使用本地主机 IP 地址 127.0.0.1。
上面显示的条目将为您提供一些主机名以进行实验。
请务必使用今天的日期,并在序列号后附加从 01 开始的计数器。上面的序列号是 2017 年 3 月 4 日的第一次更改。每当区域文件更改时,序列号都会递增。如果有使用此主服务器的辅助名称服务器,则除非序列号递增,否则它们不会更新。
将正向区域文件添加到 named.conf
但是,在您的 DNS 服务器工作之前,您需要在 /etc/named.conf 中创建一个条目,该条目将指向您的新区域文件。在顶级提示区域的条目下方但在“include”行之前添加以下行。
zone "example.com" IN {
type master;
file "example.com.zone";
};
列表 4:将这些行添加到 named.conf 文件,以将 Example.com 区域文件添加到解析器配置。
现在重启 named 以使这些更改生效。通过使用 dig 和 nsloookup 命令获取您在正向区域文件中配置的主机的 IP 地址来测试您的名称服务器。请注意,主机不必存在于网络上,dig 和 nslookup 命令才能返回 IP 地址。
dig test1.example.com
dig t1.example.com
dig mx example.com
dig mail.example.com
nslookup test3.example.com
dig www.amazon.com
请注意,除非在 /etc/resolv.conf 文件中提供了 Example.com 的域和搜索条目,否则除了 nslookup 命令外,对于这些命令,必须使用 FQDN。在这种情况下,它们可能没有提供,因此只需在本项目的所有测试中使用 FQDN。
使用根名称服务器
请注意,根名称服务器被指定为 Amazon.com 查找的权威服务器。但请记住,您正在使用 Google 公共名称服务器作为转发器。现在注释掉 named.conf 中的转发器行并重启 named。再次运行上述命令以比较返回的结果。结果应类似于列表 5 中的结果。
# dig www.amazon.com
; <<>> DiG 9.10.4-P6-RedHat-9.10.4-4.P6.fc25 <<>> www.amazon.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65004
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 4, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.amazon.com. IN A
;; ANSWER SECTION:
www.amazon.com. 1800 IN CNAME www.cdn.amazon.com.
www.cdn.amazon.com. 300 IN CNAME d3ag4hukkh62yn.cloudfront.net.
d3ag4hukkh62yn.cloudfront.net. 60 IN A 52.85.147.120
d3ag4hukkh62yn.cloudfront.net. 60 IN A 52.85.147.50
d3ag4hukkh62yn.cloudfront.net. 60 IN A 52.85.147.92
d3ag4hukkh62yn.cloudfront.net. 60 IN A 52.85.147.109
;; AUTHORITY SECTION:
d3ag4hukkh62yn.cloudfront.net. 1831 IN NS ns-1144.awsdns-15.org.
d3ag4hukkh62yn.cloudfront.net. 1831 IN NS ns-130.awsdns-16.com.
d3ag4hukkh62yn.cloudfront.net. 1831 IN NS ns-2021.awsdns-60.co.uk.
d3ag4hukkh62yn.cloudfront.net. 1831 IN NS ns-824.awsdns-39.net.
;; Query time: 3857 msec
;; SERVER: 192.168.0.203#53(192.168.0.203)
;; WHEN: Mon Mar 13 09:18:30 EDT 2017
;; MSG SIZE rcvd: 306
列表 5:对 www.amazon.com 的查找结果包含一些有趣的信息,包括各种记录类型的生存时间。
当我这样做时,第一次调用以解析 Amazon 的外部地址花费了 3857 毫秒,同时数据被定位并返回。后续执行相同查询的结果为 1 毫秒,这显示了在本地缓存解析器结果的优势。请注意答案部分行中的数字 1800、300 和 60 以及授权部分行中的 1831 — 这些是 TTL(生存时间),以秒为单位。如果您多次执行查找,这些数字将发生变化,显示记录在本地缓存中剩余的生存时间量。
创建反向区域文件
域的反向区域将提供执行反向查找的能力。许多组织在内部不做这些,但反向查找对于进行问题确定很有帮助。许多反垃圾邮件配置(例如 SpamAssassin)都查找反向查找以验证有效的电子邮件服务器。
创建反向区域文件 /var/named/example.com.rev 并添加以下内容。请务必使用适当的序列号。
; Authoritative data for example.com reverse zone
;
$TTL 1D
@ IN SOA test1.example.com root.test1.example.com. (
2017031501 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
@ IN NS epc.example.com.
example.com. IN NS epc.example.com.
1 IN PTR mail.example.com.
1 IN PTR server.example.com.
21 IN PTR test1.example.com.
22 IN PTR test2.example.com.
23 IN PTR test3.example.com.
24 IN PTR test4.example.com.
列表 6:为您的名称服务器使用此反向区域文件 example.com.rev。
您也可以将您的反向区域文件命名为 /var/named/25.168.192.in-addr.arpa,这遵循了较旧的约定。您实际上可以将其命名为您想要的任何名称,因为您将在 named.conf 文件中显式指向它,但使用这两个约定之一将使其他人更容易理解您的工作。
将反向区域添加到 named.conf
zone "25.168.192.in-addr.arpa" IN {
type master;
file "example.com.rev";
};
列表 7:将此节添加到 named.conf 文件可启用反向查找。
将列表 7 中的节添加到 /etc/named.conf 文件以指向新的反向区域。现在重新加载 named 并使用列表 8 中的命令测试您的反向区域。您的结果应类似于下面的结果。
systemctl reload named
# dig -x 192.168.25.23
; <<>> DiG 9.10.4-P6-RedHat-9.10.4-4.P6.fc25 <<>> -x 192.168.25.23
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48607
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;23.25.168.192.in-addr.arpa. IN PTR
;; ANSWER SECTION:
23.25.168.192.in-addr.arpa. 86400 IN PTR test3.example.com.
;; AUTHORITY SECTION:
25.168.192.in-addr.arpa. 86400 IN NS epc.example.com.
;; Query time: 21 msec
;; SERVER: 192.168.0.203#53(192.168.0.203)
;; WHEN: Wed Mar 15 16:18:59 EDT 2017
;; MSG SIZE rcvd: 112
列表 8:重新启动 named 后,当您对反向区域中的 IP 地址执行反向查找时,您应该会看到类似于这些的结果。
请务必测试网络中的其他一些反向条目,并尝试以下命令以及您想要实验的其他反向查找。-x 选项表示反向查找。
dig -x 192.168.25.23
dig -x 192.168.25.1
请注意,并非正向区域中具有条目的所有主机都需要在反向区域中具有条目,但如果它们这样做,则会使结果更加一致。
至此,您已经拥有一个使用 BIND 的工作名称服务器。但是,外部主机尚无法使用此名称服务器,因为防火墙尚不应配置为允许 DNS 请求。
为 DNS 配置 IPTables
如果您希望本地网络上的其他主机将您的主机用作其名称服务器,则可以执行此步骤。
您测试主机上的防火墙可能会阻止对您的主机进行名称服务访问。必须配置 IPTables 以允许 UDP(用户数据报协议)数据包在您的名称服务器上入站,以便其他主机可以使用它进行名称解析。使用以下命令添加所需的条目并保存它们。
使用 firewalld 或 IPTables 向您的防火墙添加规则,允许端口 53(域)上的入站数据包用于 UDP,并保存新的规则集。请务必在 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 行之后插入新规则,因此您必须计算过滤器表中 INPUT 行的数量才能执行此操作。以下命令中的数字 7 表示此规则将插入到现有 INPUT 规则中的第 7 位。
iptables -t filter -I INPUT 7 -p udp -m conntrack --ctstate NEW -m udp --dport 53 -j ACCEPT
如果您愿意,可以保存新的防火墙规则,如果这是一个永久安装而不是实验室项目,您会这样做。然后从您的其他主机之一使用列表 9 中的命令进行测试。@epc 参数告诉 dig 命令使用具有主机名 epc 的指定名称服务器。您应该替换为您刚刚创建的 DNS 服务器的 IP 地址,或者网络上指向您的新名称服务器的可解析主机名。当然,您始终可以将该主机名及其 IP 地址添加到用于远程测试的主机的 /etc/hosts 文件中。
# dig @epc test1.example.com
; <<>> DiG 9.10.4-P6-RedHat-9.10.4-4.P6.fc25 <<>> @epc test1.example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27957
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test1.example.com. IN A
;; ANSWER SECTION:
test1.example.com. 86400 IN A 192.168.25.21
;; AUTHORITY SECTION:
example.com. 86400 IN NS epc.both.org.
;; Query time: 0 msec
;; SERVER: 192.168.0.203#53(192.168.0.203)
;; WHEN: Mon Mar 13 08:45:34 EDT 2017
;; MSG SIZE rcvd: 92
列表 9:从同一网络上的不同主机测试您创建的名称解析器。
清理
对于清理,您应该使用适合您发行版的工具执行以下任务。如果您还没有名称服务器,您可能只想为您的网络保留此名称服务器。
- 恢复原始 /etc/hosts 文件。
- 在用于此实验室项目的解析器主机上停止 named。
- 禁用 named 服务。
- 删除区域文件。
- 恢复原始 named.conf 文件。
- 恢复原始 resolv.conf 文件。
最终想法
在我实际使用 BIND 为我的网络创建名称服务器之前,名称服务的功能对我来说似乎非常晦涩难懂。它非常简单,可以提高 DNS 查找性能。拥有您自己的名称服务器还可以防止许多由维护不善的 ISP 名称服务器引起的相对较小但令人烦恼的名称服务中断。
请注意,即使我的小 EeePC 在 Seti@Home 中以 100% 的 CPU 使用率运行,它也能非常快速地响应解析器请求。您应该能够在您拥有的任何 Linux 主机上尝试此项目,影响微乎其微。我希望你们中的许多人会尝试设置自己的名称服务器并对其进行实验。您的名称服务器安装的具体细节将取决于您的主机和网络的详细信息。
5 条评论