如何在 Ubuntu 14.04 上将 Bind 配置为权威 DNS 服务器
介绍
在学习如何配置网站和服务器时,DNS 或域名系统通常是一个很难正确掌握的组件。虽然大多数人可能会选择使用托管公司或域名注册商提供的 DNS 服务器,但创建自己的 DNS 服务器也有一些优势。
在本指南中,我们将讨论如何在 Ubuntu 14.04 机器上安装和配置 Bind9 DNS 服务器作为权威 DNS 服务器。我们将在主从配置中为我们的域设置两个绑定服务器。
先决条件和目标
要完成本指南,您首先需要熟悉一些常见的 DNS 术语。查看本指南以了解我们将在本指南中实施的概念。
您还需要至少两台服务器。一个将用于“主”DNS 服务器,我们域的区域文件将在这里生成,一个将是“辅助”服务器,它将通过传输接收区域数据,并在另一台服务器出现故障时可用.这避免了 DNS 服务器出现单点故障的危险。
与缓存或转发 DNS 服务器或多用途 DNS 服务器不同,仅权威服务器仅响应对其具有权威的区域的迭代查询。这意味着如果服务器不知道答案,它只会告诉客户端(通常是某种解析 DNS 服务器)它不知道答案,并向可能知道更多的服务器提供参考。
仅权威 DNS 服务器通常是高性能的良好配置,因为它们没有解析来自客户端的递归查询的开销。他们只关心他们设计服务的区域。
出于本指南的目的,我们实际上将引用三台服务器。上面提到的两个名称服务器,加上我们要在我们的区域内配置为主机的 Web 服务器。
我们将在本指南中使用虚拟域 example.com
。您应该将其替换为您正在配置的域。这些是我们将要配置的机器的详细信息:
Purpose | DNS FQDN | IP Address |
---|---|---|
Primary name server | ns1.example.com. | 192.0.2.1 |
Secondary name server | ns2.example.com. | 192.0.2.2 |
Web Server | www.example.com. | 192.0.2.3 |
完成本指南后,您应该为您的域区域配置了两个仅权威名称服务器。上表中间栏中的名称将能够用于访问您的各种主机。使用此配置,递归 DNS 服务器将能够将有关域的数据返回给客户端。
在名称服务器上设置主机名
在我们进入我们的名称服务器配置之前,我们必须确保我们的主机名在我们的主要和辅助 DNS 服务器上配置正确。
首先调查 /etc/hosts
文件。在文本编辑器中使用 sudo 权限打开文件:
sudo nano /etc/hosts
我们需要对其进行配置,以便它正确识别每个服务器的主机名和 FQDN。对于主名称服务器,该文件最初看起来像这样:
127.0.0.1 localhost
127.0.1.1 ns1 ns1
. . .
我们应该修改第二行以引用我们特定的主机和域组合,并将其指向我们的公共静态 IP 地址。然后我们可以在末尾添加非限定名称作为别名。对于本例中的主服务器,您可以将第二行更改为:
127.0.0.1 localhost
192.0.2.1 ns1.example.com ns1
. . .
完成后保存并关闭文件。
我们还应该修改 /etc/hostname
文件以包含我们不合格的主机名:
sudo nano /etc/hostname
ns1
我们可以通过键入以下内容将此值读入当前运行的系统:
sudo hostname -F /etc/hostname
我们想在我们的辅助服务器上完成相同的过程。
从 /etc/hosts
文件开始:
sudo nano /etc/hosts
127.0.0.1 localhost
192.0.2.2 ns2.example.com ns2
完成后保存并关闭文件。
然后,修改/etc/hostname
文件。请记住只为这个文件使用实际主机(在我们的示例中只是 ns2
):
sudo nano /etc/hostname
ns2
再次读取文件修改当前系统:
sudo hostname -F /etc/hostname
您的服务器现在应该正确设置了主机定义。
在两个名称服务器上安装绑定
在您的每个名称服务器上,您现在可以安装 Bind,我们将使用的 DNS 服务器。
Bind 软件在 Ubuntu 的默认存储库中可用,所以我们只需要更新我们的本地包索引并使用 apt
安装软件。我们还将包括文档和一些常用实用程序:
sudo apt-get update
sudo apt-get install bind9 bind9utils bind9-doc
在您的主要和辅助 DNS 服务器上运行此安装命令以获取适当的文件。
配置主绑定服务器
现在我们已经安装了软件,我们可以开始在主服务器上配置我们的 DNS 服务器。
配置选项文件
我们首先要配置的是 named.conf.options
文件。
绑定 DNS 服务器也称为 named
。主要配置文件位于 /etc/bind/named.conf
。该文件调用我们将实际配置的其他文件。
在编辑器中使用 sudo 权限打开选项文件:
sudo nano /etc/bind/named.conf.options
下面,为简洁起见,大部分注释行已被删除,但一般来说,安装后文件应如下所示:
options {
directory "/var/cache/bind";
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
我们需要在此文件中配置的主要内容是递归。由于我们正在尝试设置一个仅限权威的服务器,因此我们不想在此服务器上启用递归。我们可以在 options
块中关闭它。
我们还将默认不允许传输。稍后我们将在各个区域规范中覆盖它:
options {
directory "/var/cache/bind";
recursion no;
allow-transfer { none; };
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
完成后,保存并关闭文件。
配置本地文件
我们需要采取的下一步是指定我们希望控制该服务器的区域。区域是域的任何部分,它被委派给名称服务器进行管理,而该名称服务器还没有被子委派给其他服务器。
我们正在配置 example.com
域,我们不会将该域的任何部分的责任分派给其他服务器。所以该区域将覆盖我们的整个域。
要配置我们的区域,我们需要使用 sudo 权限打开 /etc/bind/named.conf.local
文件:
sudo nano /etc/bind/named.conf.local
除了注释之外,该文件最初为空。我们的服务器还知道其他用于一般管理的区域,但这些区域在 named.conf.default-zones
文件中指定。
首先,我们需要为我们的 example.com
域配置转发区域。转发区域是我们大多数人在讨论 DNS 时想到的传统名称到 IP 解析。我们创建一个配置块来定义我们希望配置的域区域:
zone "example.com" {
};
注意: 许多 DNS 工具、它们的配置文件和文档使用术语“master”和“slave”,而 DigitalOcean 通常更喜欢替代描述符。为避免混淆,我们选择使用术语“主要”和“次要”来表示服务器之间的关系,并且仅在配置指令需要时才使用“主”或“从”。
在此块内部,我们添加有关此区域的管理信息。我们指定此 DNS 服务器与区域的关系。这是下面示例区域中的 type master;
,因为我们将这台机器配置为我们所有区域的主要名称服务器。我们还将 Bind 指向保存定义区域的实际资源记录的文件。
我们将把我们的主要区域文件保存在 Bind 配置目录中名为 zones
的子目录中。我们将调用我们的文件 db.example.com
以借鉴 Bind 目录中其他区域文件的约定。我们的块现在看起来像这样:
zone "example.com" {
type master;
file "/etc/bind/zones/db.example.com";
};
我们想让这个区域转移到我们的辅助服务器,我们需要添加这样一行:
zone "example.com" {
type master;
file "/etc/bind/zones/db.example.com";
allow-transfer { 192.0.2.2; };
};
接下来,我们将为我们的域定义反向区域。
关于反向区域的一点
如果为您提供 IP 地址的组织没有为您提供网络范围并将该范围的责任委托给您,那么您的反向区域文件将不会被引用,而将由该组织自行处理。
对于托管服务提供商,反向映射通常由公司自己负责。例如,使用 DigitalOcean,如果在控制面板中使用机器的 FQDN 作为服务器名称,将自动创建服务器的反向映射。例如,本教程的反向映射可以通过这样命名服务器来创建:

在这些情况下,由于您没有分配到要管理的地址块,因此您应该使用此策略。下面概述的策略是为了完整性而涵盖,并在您被委派控制更大的连续地址组时使其适用。
反向区域用于将 IP 地址连接回域名。然而,域名系统最初是为正向映射设计的,因此需要一些想法来适应它以允许反向映射。
理解反向映射需要牢记的信息是:
- 在域中,地址的最具体部分位于左侧。对于 IP 地址,最具体的部分在右侧。
- 域规范中最具体的部分是子域或主机名。这是在域的区域文件中定义的。
- 每个子域又可以定义更多的子域或主机。
所有反向区域映射都在特殊域 in-addr.arpa
下定义,该域由互联网编号分配机构 (IANA) 控制。在这个域下,存在一棵树,它使用子域来映射 IP 地址中的每个八位字节。为确保 IP 地址的特异性反映正常域的特异性,IP 地址的八位字节实际上是颠倒的。
因此,IP 地址为 192.0.2.1
的主 DNS 服务器将被翻转为 1.2.0.192
。当我们将此主机规范添加为存在于 in-addr.arpa
域下的层次结构时,特定主机可以引用为 1.2.0.192.in-addr.arpa
。
由于我们在使用 DNS 时在区域文件本身中定义了单独的主机(如此处的前导“1”),因此我们要配置的区域将是 2.0.192.in-addr.arpa
。如果我们的网络供应商给了我们一个 /24 地址块,比如 192.0.2.0/24
,他们会把这个 in-addr.arpa
部分委托给我们。
现在您知道如何指定反向区域名称,实际定义与正向区域完全相同。在 example.com
区域定义下方,为您提供的网络创建一个反向区域。同样,这可能只有在您被委派控制一个地址块时才有必要:
zone "2.0.192.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.192.0.2";
};
我们选择将文件命名为 db.192.0.2
。这特定于区域配置的内容,并且比反向表示法更具可读性。
完成后保存并关闭文件。
创建前向区文件
我们现在已经告诉 Bind 我们的正向和反向区域,但我们还没有创建将定义这些区域的文件。
如果您还记得,我们将文件位置指定为位于名为 zones
的子目录中。我们需要创建这个目录:
sudo mkdir /etc/bind/zones
现在,我们可以使用 Bind 目录中一些预先存在的区域文件作为我们要创建的区域文件的模板。对于前向区域,db.local
文件将接近我们所需要的。使用 named.conf.local
文件中使用的名称将该文件复制到 zones
子目录中。
sudo cp /etc/bind/db.local /etc/bind/zones/db.example.com
在我们这样做的同时,我们也可以为反向区域复制一个模板。我们将使用 db.127
文件,因为它非常符合我们的需要:
sudo cp /etc/bind/db.127 /etc/bind/zones/db.192.0.2
现在,在文本编辑器中使用 sudo 权限打开前向区域文件:
sudo nano /etc/bind/zones/db.example.com
该文件将如下所示:
$TTL 604800
@ IN SOA localhost. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
@ IN A 127.0.0.1
@ IN AAAA ::1
我们需要做的第一件事是修改以第一个 @
符号开始并一直持续到右括号的 SOA
(权限开始)记录。
我们需要用这台机器的 FQDN 的名称替换 localhost.
。记录的这一部分用于定义将对正在定义的区域进行权威响应的任何名称服务器。这将是我们现在配置的机器,在我们的例子中是 ns1.example.com.
(注意尾随的点。这对我们的条目正确注册很重要!)。
我们还想更改下一块,它实际上是一个特殊格式的电子邮件地址,其中 @
被一个点替换。我们希望我们的电子邮件发送到域的管理员,因此传统的电子邮件是 admin@example.com
。我们会将其翻译成 admin.example.com.
:
@ IN SOA ns1.example.com. admin.example.com. (
我们需要编辑的下一块是序列号。序列号的值是 Bind 告诉它是否需要将更新的信息发送到辅助服务器的方式。
注意:未能增加序列号是导致区域更新出现问题的最常见错误之一。每次进行编辑时,您必须修改序列号。
一种常见的做法是使用递增数字的约定。一种方法是使用 YYYYMMDD 格式的日期以及添加到末尾的日期的修订号。因此,2014 年 6 月 5 日进行的第一次修订的序列号可能为 2014060501,当天晚些时候进行的更新的序列号可能为 2014060502。该值可以是 10 位数字。
为了易于使用而采用约定是值得的,但为了让我们的演示简单一些,我们现在将我们的设置为 5
:
@ IN SOA ns1.example.com. admin.example.com. (
5 ; Serial
接下来,我们可以删除文件中的最后三行(底部以 @
开头的行),因为我们将自己制作。
我们要在 SOA 记录之后建立的第一件事是我们区域的名称服务器。我们指定域,然后按名称指定对该区域具有权威性的两个名称服务器。由于这些名称服务器将是域本身内的主机,因此它看起来有点自我引用。
对于我们的指南,它看起来像这样。再次注意结尾的点!:
; Name servers
example.com. IN NS ns1.example.com.
example.com. IN NS ns2.example.com.
由于区域文件的目的主要是将主机名和服务映射到特定地址,我们还没有完成。任何读取此区域文件的软件都想知道 ns1
和 ns2
服务器的位置,以便访问权威区域。
所以接下来,我们需要创建 A
记录,将这些名称服务器名称关联到我们名称服务器的实际 IP 地址:
; A records for name servers
ns1 IN A 192.0.2.1
ns2 IN A 192.0.2.2
现在我们有了 A 记录来成功地将我们的名称服务器解析为正确的 IP 地址,我们可以添加任何其他记录。请记住,我们在其中一台主机上有一个 Web 服务器,我们想用它来为我们的网站提供服务。我们会将对通用域(在本例中为 example.com
)的请求以及对 www
主机的请求指向该主机。它看起来像这样:
; Other A records
@ IN A 192.0.2.3
www IN A 192.0.2.3
您可以通过创建额外的 A
记录来添加任何需要定义的额外主机。请参考我们的 DNS 基础知识指南,以熟悉创建附加记录的一些选项。
完成后,您的文件应如下所示:
$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
5 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
; Name servers
example.com. IN NS ns1.example.com.
example.com. IN NS ns2.example.com.
; A records for name servers
ns1 IN A 192.0.2.1
ns2 IN A 192.0.2.2
; Other A records
@ IN A 192.0.2.3
www IN A 192.0.2.3
完成后保存并关闭文件。
创建反向区域文件
现在,我们已经配置了正向区域,但我们需要设置我们在配置文件中指定的反向区域文件。我们已经在上一节的开头创建了文件。
使用 sudo 权限在文本编辑器中打开文件:
sudo nano db.192.0.2
该文件应如下所示:
$TTL 604800
@ IN SOA localhost. root.localhost. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
1.0.0 IN PTR localhost.
我们将经历许多与前区相同的程序。首先,调整域名、管理员电子邮件和序列号,使其与上一个文件中的完全匹配(序列号可以不同,但应递增):
@ IN SOA example.com. admin.example.com. (
5 ; Serial
再次,擦除 SOA
记录右括号下的行。我们将获取网络范围内每个 IP 地址的最后一个八位字节,并使用 PTR
记录将其映射回该主机的 FQDN。每个 IP 地址应该只有一个 PTR
记录以避免在某些软件中出现问题,因此您必须选择要反向映射到的主机名。
例如,如果您设置了邮件服务器,您可能希望设置到邮件名称的反向映射,因为许多系统使用反向映射来验证地址。
首先,我们需要再次设置我们的名称服务器:
; Name servers
IN NS ns1.example.com.
IN NS ns2.example.com.
接下来,您将使用您所引用的 IP 地址的最后一个八位字节,并将其指向您想要返回的完全限定域名。对于我们的例子,我们将使用这个:
; PTR Records
1 IN PTR ns1.example.com.
2 IN PTR ns2.example.com.
3 IN PTR www.example.com.
完成后,该文件应如下所示:
$TTL 604800
@ IN SOA example.com. admin.example.com. (
5 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
; Name servers
IN NS ns1.example.com.
IN NS ns2.example.com.
; PTR records
1 IN PTR ns1.example.com.
2 IN PTR ns2.example.com.
3 IN PTR www.example.com.
完成后保存并关闭文件。
测试文件并重新启动服务
主服务器的配置现已完成,但我们仍需要实施更改。
在我们重新启动我们的服务之前,我们应该测试我们所有的配置文件以确保它们配置正确。我们有一些工具可以检查每个文件的语法。
首先,我们可以使用 named-checkconf
命令检查 named.conf.local
和 named.conf.options
文件。由于这两个文件都是骨架 named.conf
文件的来源,它将测试我们修改的文件的语法。
sudo named-checkconf
如果返回时没有任何消息,则意味着 named.conf.local
和 named.conf.options
文件在语法上是有效的。
接下来,您可以通过将区域处理的域和区域文件位置传递给 named-checkzone
命令来检查您的个人区域文件。因此,对于我们的指南,您可以通过键入以下内容来检查前向区域文件:
sudo named-checkzone example.com /etc/bind/zones/db.example.com
如果你的文件没有问题,它应该告诉你它加载了正确的序列号并给出“OK”信息;
zone example.com/IN: loaded serial 5
OK
如果您遇到任何其他消息,则意味着您的区域文件有问题。通常,消息会详细说明哪些部分无效。
您可以通过传递 in-addr.arpa
地址和文件名来检查反向区域。对于我们的演示,我们将输入:
sudo named-checkzone 2.0.192.in-addr.arpa /etc/bind/zones/db.192.0.2
同样,这应该会为您提供有关加载正确序列号的类似消息:
zone 2.0.192.in-addr.arpa/IN: loaded serial 5
OK
如果您的所有文件都在签出,您可以重新启动绑定服务:
sudo service bind9 restart
您应该通过键入以下内容来检查日志:
sudo tail -f /var/log/syslog
密切关注此日志以确保没有错误。
配置辅助绑定服务器
现在我们已经配置了主服务器,我们可以继续设置辅助服务器。这将比主服务器容易得多。
配置选项文件
同样,我们将从 named.conf.options
文件开始。在文本编辑器中使用 sudo 权限打开它:
sudo nano /etc/bind/named.conf.options
我们将对该文件进行与我们对主服务器文件所做的完全相同的修改。
options {
directory "/var/cache/bind";
recursion no;
allow-transfer { none; };
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
完成后保存并关闭文件。
配置本地配置文件
接下来,我们将在辅助服务器上配置 named.conf.local
文件。在文本编辑器中使用 sudo 权限打开它:
sudo nano /etc/bind/named.conf.local
在这里,我们将像在主服务器上所做的那样创建每个区域规范。但是,值和一些参数会有所不同。
首先,我们将在前沿区开展工作。以与在主文件中相同的方式启动它:
zone "example.com" {
};
这一次,我们要将 type
设置为 slave
,因为此服务器充当此区域的辅助服务器。这只是意味着它通过传输而不是本地系统上的文件接收其区域文件。此外,我们将只指定相对文件名而不是区域文件的绝对路径。
这样做的原因是,对于辅助区域,Bind 存储文件 /var/cache/bind
。绑定已经配置为在这个目录位置查找,所以我们不需要指定路径。
对于我们的前方区域,这些详细信息将如下所示:
zone "example.com" {
type slave;
file "db.example.com";
};
最后,我们将通过 IP 地址指定主要服务器,而不是 allow-transfer
指令,该服务器将从该服务器接受区域传输。这是在名为 masters
的指令中完成的:
zone "example.com" {
type slave;
file "db.example.com";
masters { 192.0.2.1; };
};
这完成了我们的前向区域规范。我们可以使用同样的格式来处理我们的反向区域规范:
zone "2.0.192.in-addr.arpa" {
type slave;
file "db.192.0.2";
masters { 192.0.2.1; };
};
完成后,您可以保存并关闭文件。
测试文件并重新启动服务
我们实际上不必在辅助机器上创建任何实际的区域文件,因为正如我们之前提到的,该服务器将从主服务器接收区域文件。所以我们准备测试。
同样,我们应该检查配置文件的语法。由于我们没有任何区域文件要检查,我们只需要使用 named-checkconf
工具:
sudo named-checkconf
如果返回时没有任何错误,则意味着您修改的文件没有语法错误。
如果是这种情况,您可以重新启动绑定服务:
sudo service bind9 restart
使用以下命令检查主服务器和辅助服务器上的日志:
sudo tail -f /var/log/syslog
您应该会看到一些条目,表明区域文件已正确传输。
将权限委托给您的名称服务器
您的权威名称服务器现在应该已完全配置。但是,您仍然需要将域的权限委托给您的名称服务器。
为此,您必须访问您购买域名的网站。界面和术语可能会有所不同,具体取决于您使用的域名注册商。
在您的域设置中,寻找一个选项,允许您指定您希望使用的名称服务器。由于我们的名称服务器在我们的域中,这是一个特例。
注册服务商不需要通过使用 NS 记录简单地为区域委派权限,而是需要创建粘合记录。粘合记录是一种 A 记录,它在指定要向其授权的名称服务器之后指定名称服务器的 IP 地址。
通常,委托只列出将处理域权限的名称服务器,但是当名称服务器在域本身内时,父区域中的名称服务器需要一个 A 记录。如果这没有发生,DNS 解析器将陷入循环,因为它永远无法找到域名称服务器的 IP 地址来遵循委托路径。
因此,您需要在域注册商的控制面板中找到一个部分,以允许您指定名称服务器和它们的 IP 地址。
作为演示,注册商 Namecheap 有两个不同的名称服务器部分。
有一个名为 \Nameserver Registration 的部分允许您为域内的名称服务器指定 IP 地址:

在内部,您将能够输入域中存在的名称服务器的 IP 地址:

这将创建 A 记录,作为父区域文件中所需的粘合记录。
完成此操作后,您应该能够将活动名称服务器更改为您域的服务器。在 NameCheap 中,这是使用“域名服务器设置”菜单选项完成的:

在这里,您可以告诉它使用您添加的名称服务器作为您站点的权威服务器:

更改可能需要一段时间才能传播,但您应该会在接下来的 24-48 小时内看到大多数注册商正在使用您的名称服务器的数据。
结论
您现在应该有两个配置为服务器域的仅权威 DNS 服务器。当您获得更多时,这些可用于存储其他域的区域信息。
配置和管理您自己的 DNS 服务器可让您最大程度地控制 DNS 记录的处理方式。您可以进行更改并确保所有相关的 DNS 数据在源头都是最新的。虽然其他 DNS 解决方案可能会使此过程更容易,但重要的是要知道您有多种选择并了解更多打包解决方案中发生的情况。