4. DNS服务器软件选型与安装

DNS 服务能否稳定运行,第一步并不在于写 zone 文件,而在于选对软件。不同 DNS 软件在定位、递归/权威能力、数据后端、运维接口和许可协议上差异明显:BIND 是“全能老将”,Unbound 专注递归解析,PowerDNS 把权威与递归拆成两个独立组件并支持数据库后端,Windows DNS 则深度绑定 AD 域环境。选型错误往往在后期才暴露,例如用 Unbound 承载大量权威区、用 BIND 做高并发纯递归缓存,都会带来不必要的复杂度。

四类主流软件的能力边界

BIND 9 同时支持权威(authoritative)与递归(recursive)角色,支持主从复制、TSIG 签名、DNSSEC 在线签名、RPZ、视图(view)等特性,配置文件为 named.conf,区文件采用标准 RFC 1035 文本格式。它的优势是功能完整、文档与社区资料极多,适合作为教学与中小规模权威/递归一体服务器;代价是配置语法偏繁琐,递归与权威混布时需要谨慎隔离。

Unbound 由 NLnet Labs 开发,定位是高性能、安全的递归解析器,只做递归与缓存,不做权威区托管。它默认启用 DNSSEC 验证、QNAME 最小化、缓存投毒防护,配置为 unbound.conf,结构比 BIND 简洁。适合作为企业出口递归解析器或本地缓存,与 BIND/PowerDNS 权威服务器配合使用。

PowerDNS 分为 Authoritative(pdns_server)与 Recursor(pdns_recursor)两个独立进程。权威端支持 gmysql、gpgsql、gsqlite3、ldap 等多种后端,区数据可存于数据库,便于通过 SQL 或 API 批量管理;Recursor 则专注递归。它适合需要动态区管理、大规模记录、API 自动化的场景,但引入数据库后运维链路更长。

Windows DNS 是 Windows Server 角色,与 Active Directory 集成后可实现安全动态更新、AD 集成区、条件转发、DNSSEC 签名等。它的管理以图形界面和 PowerShell 为主,适合以 AD 为核心的内网;跨平台与脚本化能力弱于前三者,且许可成本需计入。

DNS 软件选型:角色定位与数据后端对照 纯递归 / 缓存 权威 + 动态管理 BIND 9 权威 + 递归(可分离) 后端:文本 zone 文件 配置:named.conf 特性:视图 / TSIG / RPZ Unbound 仅递归 / 缓存 后端:内存缓存 配置:unbound.conf 特性:DNSSEC 验证默认开 PowerDNS 权威 / 递归 双组件 后端:SQL / LDAP / API 配置:pdns.conf 特性:动态区 / REST API Windows DNS 权威(AD 集成) 后端:AD / 文件 配置:GUI / PowerShell 特性:安全动态更新 实验环境选型决策路径 需要托管权威区? 是 → BIND / PowerDNS 只需递归缓存? 是 → Unbound 需 API / 数据库? 是 → PowerDNS AD 域内网? 是 → Windows DNS 实验建议:BIND 作权威 + Unbound 作递归,二者分离部署,便于观察递归与权威的边界 若需动态区管理,再引入 PowerDNS + SQLite 作为对照实验

实验环境部署:以 BIND + Unbound 分离为例

下面以一台 Linux 主机(示例为 Ubuntu 22.04,IP 192.0.2.10)为例,部署“Unbound 递归 + BIND 权威”的分离结构。示例参数均为教学假设,实际使用时请替换为你的网段与域名。

第一步,安装软件包:

sudo apt update
sudo apt install -y bind9 bind9utils unbound dnsutils

第二步,配置 BIND 权威服务器。编辑 /etc/bind/named.conf.options,关闭递归并只监听本机与内网:

options {
    directory "/var/cache/bind";
    recursion no;
    listen-on { 127.0.0.1; 192.0.2.10; };
    listen-on-v6 { none; };
    allow-transfer { none; };
    dnssec-validation no;
};

在 /etc/bind/named.conf.local 中声明实验区 lab.example:

zone "lab.example" {
    type master;
    file "/etc/bind/db.lab.example";
};

创建区文件 /etc/bind/db.lab.example,注意 SOA 中的序列号、刷新、重试、过期与最小 TTL 五个时间参数:

$TTL 3600
@   IN  SOA ns1.lab.example. admin.lab.example. (
        2024050401 ; serial
        3600       ; refresh
        900        ; retry
        604800     ; expire
        300 )      ; minimum
@       IN  NS   ns1.lab.example.
ns1     IN  A    192.0.2.10
www     IN  A    192.0.2.20
mail    IN  A    192.0.2.30
@       IN  MX   10 mail.lab.example.

检查语法并启动:

sudo named-checkconf
sudo named-checkzone lab.example /etc/bind/db.lab.example
sudo systemctl restart bind9
sudo systemctl enable bind9

第三步,配置 Unbound 递归解析器。编辑 /etc/unbound/unbound.conf.d/lab.conf,让它监听 192.0.2.10 的 53 端口,并把 lab.example 转发给本机 BIND:

server:
    interface: 192.0.2.10
    port: 53
    access-control: 192.0.2.0/24 allow
    do-daemonize: yes
    verbosity: 1

forward-zone:
    name: "lab.example"
    forward-addr: 192.0.2.10@5353

这里有一个关键点:Unbound 与 BIND 不能同时占用 53 端口。实验中将 BIND 的监听端口改为 5353(在 named.conf.options 中加 listen-on port 5353 { 192.0.2.10; };),Unbound 占用 53,对外提供递归与转发。这样既保留了权威区的独立性,又让客户端只面对一个解析入口。

第四步,验证。使用 dig 分别查询权威与递归:

dig @192.0.2.10 -p 5353 www.lab.example A +short
dig @192.0.2.10 www.lab.example A +short
dig @192.0.2.10 www.baidu.com A +short

预期结果:第一条返回 192.0.2.20,说明 BIND 权威区正常;第二条同样返回 192.0.2.20,说明 Unbound 转发到 BIND 生效;第三条返回公网地址,说明 Unbound 递归解析正常。若第二条超时,应检查 Unbound 的 forward-zone 是否指向 5353 端口,以及 BIND 是否真的监听在 5353。

实验环境建议把权威与递归分到不同 IP 或不同端口,避免“递归查询被权威拒绝”或“权威区被递归缓存污染”两类常见问题。生产环境还应启用 TSIG 保护主从复制、限制 allow-query 范围,并对递归服务做访问控制。

选型对照与常见误区

软件权威递归数据后端典型场景
BIND 9支持支持文本 zone教学、中小权威/递归一体
Unbound不支持强内存缓存出口递归、本地缓存
PowerDNS支持支持(独立组件)SQL/LDAP/API动态区、大规模记录
Windows DNS支持支持AD/文件AD 域内网

常见误区有三:一是把 Unbound 当权威服务器用,结果发现无法托管 zone;二是 BIND 同时开递归与权威却不做视图隔离,导致缓存被外部查询利用;三是 PowerDNS 引入数据库后忽略连接池与索引,查询延迟反而高于文本 zone。选型时应先明确“这台服务器是给谁解析、解析什么、数据从哪来”,再决定软件与后端,而不是先装软件再补需求。