在Linux环境中,“装DNS”通常包含两种含义:一是将Linux系统配置为DNS客户端,使其能够查询域名;二是在Linux系统上搭建并运行一个DNS服务器,用于提供域名解析服务,后者功能更强大,应用场景也更广泛,例如构建企业内部域名解析、加速本地网络访问、实现网络访问控制等,本文将重点介绍如何在Linux上搭建一个功能完整的DNS服务器,我们将使用业界标准软件BIND(Berkeley Internet Name Domain)来完成这一任务。

为什么需要自建DNS服务器?
在公共DNS服务(如8.8.8.8或114.114.114.114)如此便捷的今天,搭建私有DNS服务器依然具有不可替代的价值,对于局域网环境,私有DNS可以实现主机名到IP地址的便捷映射,例如通过server.lan直接访问内部服务器,无需记忆复杂的IP地址,它能显著提升解析速度,因为本地查询避免了向外网请求的延迟,它提供了更高的安全性和可控性,管理员可以自定义解析规则,例如屏蔽特定广告域名或恶意网站,或将内部服务流量引导至指定服务器,搭建和维护DNS服务器是深入理解网络基础架构的绝佳实践。
核心组件与安装步骤
BIND是Linux上最流行、功能最强大的DNS软件套件,其核心守护进程名为named。
第一步:安装BIND软件
在不同的Linux发行版中,安装命令略有不同。
对于基于Debian或Ubuntu的系统,可以使用以下命令:
sudo apt update sudo apt install bind9 bind9utils bind9-doc
对于基于CentOS、RHEL或Fedora的系统,则使用:
sudo dnf install bind bind-utils
第二步:理解核心配置文件
BIND的配置主要围绕几个核心文件展开,通常位于/etc/bind/(Debian/Ubuntu)或/etc/named/(CentOS/RHEL)目录下。
named.conf:主配置文件,通过include指令引入其他配置文件。named.conf.options:定义全局选项,如监听端口、转发器、安全设置等。named.conf.local:用于定义本地管理的DNS区域,这是我们配置的重点。
第三步:配置本地DNS区域
我们将创建一个名为example.lan的内部域,用于解析局域网内的主机,编辑named.conf.local文件(路径可能因系统而异):
sudo nano /etc/bind/named.conf.local
在文件中添加以下内容,定义一个正向解析区域(将域名解析为IP):

zone "example.lan" {
type master;
file "/etc/bind/db.example.lan";
allow-update { none; };
};
这里,type master表明这是主区域服务器,file指定了该区域数据的具体存储文件。
第四步:创建区域数据库文件
我们需要创建上一步中指定的区域数据库文件db.example.lan,可以复制一个模板文件进行修改:
sudo cp /etc/bind/db.local /etc/bind/db.example.lan sudo nano /etc/bind/db.example.lan
如下,这是一个包含多种记录类型的示例:
$TTL 604800
@ IN SOA ns1.example.lan. admin.example.lan. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.example.lan.
@ IN A 192.168.1.10
ns1 IN A 192.168.1.10
www IN A 192.168.1.20
mail IN A 192.168.1.30
api IN CNAME www.example.lan.
@ IN MX 10 mail.example.lan.
下表解释了这些记录的含义:
| 记录类型 | 示例 | 功能说明 |
|---|---|---|
| SOA | ns1.example.lan. admin.example.lan. |
起始授权机构记录,定义了该区域的主服务器和管理员邮箱。 |
| NS | ns1.example.lan. |
名称服务器记录,指定负责解析该区域的DNS服务器。 |
| A | www IN A 192.168.1.20 |
地址记录,将主机名www.example.lan解析到IPv4地址168.1.20。 |
| CNAME | api IN CNAME www.example.lan. |
别名记录,将api.example.lan指向www.example.lan,它们拥有相同的IP地址。 |
| MX | @ IN MX 10 mail.example.lan. |
邮件交换记录,指示发送到@example.lan的邮件应由服务器mail.example.lan处理。 |
注意:每次修改此文件后,都应将SOA记录中的Serial序列号加一,以便通知辅助DNS服务器或缓存更新数据。
启动与验证服务
配置完成后,即可启动并启用BIND服务。
sudo systemctl start named sudo systemctl enable named
使用systemctl status named检查服务状态,确保其正常运行,如果遇到问题,可以通过journalctl -u named查看详细日志。
验证DNS解析功能最有效的工具是dig和nslookup,在DNS服务器本机上执行:

# 使用dig查询www主机 dig @localhost www.example.lan # 使用nslookup查询mail主机 nslookup mail.example.lan localhost
如果命令返回的ANSWER SECTION中包含了正确的IP地址,则说明DNS服务器搭建成功。
为了让局域网内其他机器也能使用此DNS服务,需要将它们的DNS设置指向这台服务器的IP地址(例如168.1.10),在Linux客户端上,这通常通过修改/etc/resolv.conf或通过网络管理工具(如Netplan、NetworkManager)的配置文件来实现。
相关问答FAQs
问题1:修改了区域文件后,如何让DNS服务器立即生效?
解答: 在修改了区域数据库文件(如db.example.lan)并增加了SOA记录中的序列号后,你需要通知BIND守护进程重新加载配置,最平滑的方式是使用rndc(Remote Name Daemon Control)工具执行重载命令:
sudo rndc reload
这个命令会重新加载所有配置和区域文件,而不会中断现有的DNS查询服务,如果rndc不可用,也可以使用systemctl:
sudo systemctl reload named
问题2:我的DNS服务器只能解析我设置的内部域名,无法解析外网域名(如google.com),这是为什么?
解答: 这是因为你搭建的DNS服务器目前只被授权为example.lan这个区域的主服务器,它并不知道如何解析其他公共域名,要解决这个问题,需要配置“转发器”,编辑named.conf.options文件,在options块内添加forwarders指令,指向公共DNS服务器:
options {
// ... 其他选项 ...
forwarders {
8.8.8.8;
1.1.1.1;
};
};
保存文件后,重新加载BIND服务(sudo rndc reload),当你的DNS服务器收到一个它不负责的域名请求时,它会将请求转发给这里设置的公共DNS服务器,并将结果返回给客户端,从而实现完整的域名解析功能。