域名服务(DNS)负责在 IP 地址和完全限定域名(FQDN)之间转换,让人们无需记忆 IP。运行 DNS 的计算机称为域名服务器。Ubuntu 提供 Berkeley Internet Naming Daemon(BIND),它是 Linux 上常见的域名服务器程序。
安装 DNS
安装 bind9:
sudo apt install bind9
dnsutils 包包含测试与排查工具,通常已经安装,也可以执行:
sudo apt install dnsutils
配置概览
BIND9 有多种配置方式,常见的是缓存服务器、主服务器与从服务器。
- 缓存服务器负责查询并记住结果,下次可复用。
- 主服务器从本机文件读取某个区域的数据,是该区域的权威服务器。
- 从服务器从其他权威服务器获取区域数据。
配置文件
文件位于 /etc/bind。主配置 named.conf 按软件包默认结构包含:
named.conf.options:全局选项。named.conf.local:自定义区域。named.conf.default-zones:localhost、其反向区域和根提示等默认区域。
根服务器信息由 dns-root-data 包的 /usr/share/dns/root.hints 提供,并由默认区域配置引用。Ubuntu 18.04 LTS 及更早时期使用 /etc/bind/db.root。
同一服务器可以同时承担缓存、主服务器与从服务器角色,取决于具体区域。例如对一个区域权威负责,对另一个区域提供从服务,同时为局域网缓存查询。
配置缓存域名服务器
默认配置已作为缓存服务器运行。编辑 /etc/bind/named.conf.options,在 options 中添加运营商 DNS 的 forwarders:
options {
forwarders {
1.2.3.4;
5.6.7.8;
};
};
将示例地址替换为真实 DNS 服务器地址。然后重启:
sudo systemctl restart bind9.service
测试方式见下文 dig 部分。
配置主服务器
本节为 example.com 配置主服务器,可以替换为自己的 FQDN。
正向区域文件
编辑 /etc/bind/named.conf.local,添加:
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
};
注意:如果通过 DDNS 等方式自动更新区域文件,应使用 /var/lib/bind/db.example.com,而不是 /etc/bind 下的路径。
创建 /etc/bind/db.example.com。直到 Ubuntu 25.04,可从 db.local 等模板复制。
填写服务器 FQDN,并保留结尾点号;填写域名服务器 IP,以及有效邮箱,但用点号替换 @,末尾也加点。例如 root@example.com 写为 root.example.com.。可用分号添加注释。
为基础域名 example.com 和本例域名服务器 ns.example.com 创建 A 记录:
;
; BIND data file for example.com
;
$TTL 604800
@ IN SOA example.com. root.example.com. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS ns.example.com.
@ IN A 192.168.1.10
@ IN AAAA 2001:db8::10
ns IN A 192.168.1.10
每次修改区域文件都必须增加 Serial。如果重启前一次做了多项修改,只需增加一次。可以继续在文件底部添加记录,类型说明见下文。
提示:很多管理员用最后修改日期作为序列号,例如 2020012100,格式为 yyyymmddss,ss 是当日序号。
修改完成后重启生效:
sudo systemctl restart bind9.service
反向区域文件
正向解析已能将名称转为 IP,还需要反向区域把地址转为名称。在 named.conf.local 添加:
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192";
};
将 1.168.192 替换为所用网络前三个八位组的反向排列。db.192 文件名也应按网络第一个八位组相应命名。
创建 db.192,并修改与正向区域相同的选项:
;
; BIND reverse data file for local 192.168.1.XXX net
;
$TTL 604800
@ IN SOA ns.example.com. root.example.com. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns.
10 IN PTR ns.example.com.
反向区域每次修改也要递增 Serial。正向文件中每个不同地址的 A 记录,都需要对应 PTR 记录。
创建后重启:
sudo systemctl restart bind9.service
配置从服务器
强烈建议配置从服务器,确保主服务器不可用时域名仍可解析。
先在主服务器的正反向区域中添加 allow-transfer:
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
allow-transfer { 192.168.1.11; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192";
allow-transfer { 192.168.1.11; };
};
192.168.1.11 替换为从服务器地址,然后重启主服务器:
sudo systemctl restart bind9.service
在从服务器同样安装 bind9,再向 named.conf.local 添加:
zone "example.com" {
type secondary;
file "db.example.com";
masters { 192.168.1.10; };
};
zone "1.168.192.in-addr.arpa" {
type secondary;
file "db.192";
masters { 192.168.1.10; };
};
将 192.168.1.10 替换为主服务器地址,然后重启从服务器:
sudo systemctl restart bind9.service
/var/log/syslog 应出现类似内容。原文为排版对部分行进行了换行:
client 192.168.1.10#39448: received notify for zone '1.168.192.in-addr.arpa'
zone 1.168.192.in-addr.arpa/IN: Transfer started.
transfer of '100.18.172.in-addr.arpa/IN' from 192.168.1.10#53:
connected using 192.168.1.11#37531
zone 1.168.192.in-addr.arpa/IN: transferred serial 5
transfer of '100.18.172.in-addr.arpa/IN' from 192.168.1.10#53:
Transfer completed: 1 messages,
6 records, 212 bytes, 0.002 secs (106000 bytes/sec)
zone 1.168.192.in-addr.arpa/IN: sending notifies (serial 5)
client 192.168.1.10#20329: received notify for zone 'example.com'
zone example.com/IN: Transfer started.
transfer of 'example.com/IN' from 192.168.1.10#53: connected using 192.168.1.11#38577
zone example.com/IN: transferred serial 5
transfer of 'example.com/IN' from 192.168.1.10#53: Transfer completed: 1 messages,
8 records, 225 bytes, 0.002 secs (112500 bytes/sec)
注意:只有主服务器 Serial 大于从服务器,才会传送区域。要主动通知其他从服务器变更,可加入 also-notify:
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
allow-transfer { 192.168.1.11; };
also-notify { 192.168.1.11; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192";
allow-transfer { 192.168.1.11; };
also-notify { 192.168.1.11; };
};
非权威区域文件默认位于 /var/cache/bind/。AppArmor 也允许 named 写入此目录,更多说明见 AppArmor 文档。
测试配置
resolv.conf
先将域名服务器 IP 加入客户端解析配置。主服务器自身以及另一台主机都应配置,以便交叉确认。具体方法见 DNS 客户端配置。最终 /etc/resolv.conf 的 nameserver 应指向 127.0.0.53,并包含搜索域:
nameserver 127.0.0.53
search example.com
查看本地解析器实际使用哪个 DNS:
resolvectl status
也应在客户端配置从服务器地址,防范主服务器不可用。
dig
安装 dnsutils 后,可用 dig 测试。首先查询回环地址,确认 BIND9 监听 53 端口:
dig -x 127.0.0.1
;; Query time: 1 msec
;; SERVER: 192.168.1.10#53(192.168.1.10)
缓存服务器可以查询外部域名,观察末尾耗时:
dig ubuntu.com
;; Query time: 49 msec
再次查询,时间应缩短:
;; Query time: 1 msec
ping
使用 ping 发送 ICMP 回显,展示应用如何通过 DNS 解析主机名:
ping example.com
原文给出的解析输出示例如下:
PING ns.example.com (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.800 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.813 ms
named-checkzone
bind9 包内的 named-checkzone 可在重启生效前检查区域文件。测试正向区域:
named-checkzone example.com /etc/bind/db.example.com
zone example.com/IN: loaded serial 6
OK
测试反向区域:
named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192
zone 1.168.192.in-addr.arpa/IN: loaded serial 3
OK
你的序列号可能与示例不同。
临时启用查询日志
rndc 无需重启或修改文件,就能快速开关查询日志。启用:
sudo rndc querylog on
关闭:
sudo rndc querylog off
默认发送到 syslog,并显示在 /var/log/syslog:
Jan 20 19:40:50 new-n1 named[816]: received control channel command 'querylog on'
Jan 20 19:40:50 new-n1 named[816]: query logging is now on
Jan 20 19:40:57 new-n1 named[816]: client @0x7f48ec101480 192.168.1.10#36139 (ubuntu.com): query: ubuntu.com IN A +E(0)K (192.168.1.10)
注意:查询日志量可能非常大。
日志配置
BIND9 日志选项很多,最重要的是 channel 与 category,分别决定日志位置和内容。未指定时默认:
logging {
category default { default_syslog; default_debug; };
category unmatched { null; };
};
若希望把 DNS 查询调试信息写入独立文件,需要配置目标 channel 与记录查询的 category。在 named.conf.local 添加:
logging {
channel query.log {
file "/var/log/named/query.log";
severity debug 3;
};
category queries { query.log; };
};
debug 级别可设为 1–3,未指定时默认为 1。
named 以 bind 用户运行,因此需要创建目录并更改所有者:
sudo mkdir /var/log/named
sudo chown bind:bind /var/log/named
然后重启:
sudo systemctl restart bind9.service
此后 query.log 应不断写入查询信息。更高级的配置见文末资料。
常见记录类型
A 记录
建立主机名与 IPv4 地址的对应关系:
www IN A 192.168.1.12
CNAME 记录
为现有 A 记录创建别名。原文提醒,不应创建指向另一条 CNAME 的 CNAME:
web IN CNAME www
MX 记录
指定邮件投递服务器,目标必须指向 A 记录,而不是 CNAME:
@ IN MX 1 mail.example.com.
mail IN A 192.168.1.13
NS 记录
指定保存区域副本的服务器,用于定义主、从服务器。目标应有 A 记录,不能是 CNAME:
@ IN NS ns.example.com.
@ IN NS ns2.example.com.
ns IN A 192.168.1.10
ns2 IN A 192.168.1.11
进一步阅读
- 安装 DNSSEC
- BIND9 上游文档
- 经典书籍《DNS and BIND》,原文提到第五版;另有《DNS and BIND on IPv6》。
原文:Domain Name Service (DNS)。作者/维护者:Canonical Ubuntu Server 文档贡献者。本文为原文的中文译文;代码保留原文内容。











暂无评论内容