当前位置:首页>Linux>在 Rocky Linux 10 上搭建本地 DNS 缓存解析器(Unbound 实战指南)

在 Rocky Linux 10 上搭建本地 DNS 缓存解析器(Unbound 实战指南)

  • 2026-09-09 04:58:16
在 Rocky Linux 10 上搭建本地 DNS 缓存解析器(Unbound 实战指南)

1. 认识 Unbound

Unbound 是由 NLnet Labs 开发的一款轻量级、支持 DNSSEC 验证的递归 DNS 解析器。与 BIND、PowerDNS 这类权威 DNS 服务器不同,Unbound 的核心职责不是托管 DNS 区域,而是:

  • 解析 DNS 查询
  • 将结果缓存到内存
  • 再次请求同一域名时,直接从缓存返回

兼容性说明:本文的操作步骤同样适用于 Rocky Linux 10、RHEL 10 和 AlmaLinux 10。这三个发行版都通过 dnf 提供相同的 unbound 软件包,配置文件路径和运行行为基本一致。

2. 实验环境

本指南使用两台 Rocky Linux 10 主机:

角色IP 地址主机名
DNS 服务器
192.168.1.50
resolver.haopythonlocal.com
客户端
192.168.1.75
app01.haopythonlocal.com

DNS 服务器负责运行 Unbound,客户端则通过它进行 DNS 查询。

安装之前,请确保 DNS 服务器的主机名正确且IP 地址为静态。因为客户端会持续向这台服务器发起 DNS 请求,一旦 IP 变动,所有客户端都需要手动更新 DNS 配置。

在 DNS 服务器上执行以下命令,确认主机名和 IP:

hostnamectl
ip -4 addr show

可以看到主机名为 resolver.haopythonlocal.com,网卡 IP 为 192.168.1.50。

3. 安装 Unbound

先更新系统软件包,然后安装 Unbound 和 bind-utils:

sudo dnf update -y
sudo dnf install -y unbound bind-utils

bind-utils 包里包含了 dig 命令,这是测试 DNS 最趁手的工具。稍后我们会用它来验证 Unbound 是否正常解析和缓存。

修改配置前,建议先备份默认配置文件,万一改错了可以快速恢复:

sudo cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.orig

4. 配置 Unbound

用vim编辑器打开配置文件:

sudo vim /etc/unbound/unbound.conf

在 server: 段中添加或修改以下配置:

server:
interface:192.168.1.50
interface:127.0.0.1
port:53

do-ip4:yes
do-udp:yes
do-tcp:yes

access-control:127.0.0.0/8allow
access-control:192.168.1.0/24allow
access-control:0.0.0.0/0refuse

hide-identity:yes
hide-version:yes

verbosity:1
logfile:"/var/log/unbound.log"
use-syslog:no

# 配置项解读

配置项作用说明
interface
指定 Unbound 监听 DNS 请求的 IP。这里同时监听内网 IP(192.168.1.50)和回环地址(127.0.0.1),既满足本机使用,也允许局域网其他设备接入。
do-ip4 / do-udp / do-tcp
启用 IPv4,并允许通过 UDP 和 TCP 接收 DNS 查询,覆盖标准 DNS 传输协议。
access-control
访问控制白名单。仅允许本机和 192.168.1.0/24 网段访问,其余全部拒绝。
hide-identity / hide-version
隐藏 Unbound 的身份和版本号,防止信息泄露,提升一点安全性。
verbosity / logfile / use-syslog
日志控制。verbosity: 1 输出基本运行日志,独立日志文件便于后续排错。

DNSSEC 支持:Rocky Linux 10 上的 Unbound 默认开启 DNSSEC 验证,使用根信任锚自动校验签名响应,大多数情况下无需额外配置。

# 配置上游转发器

默认情况下,Unbound 会执行完整的递归查询(直接联系根 DNS 服务器)。但在大多数场景下,转发到可信的上游 DNS 提供商更简单、也更快。

在配置文件末尾追加以下内容:

forward-zone:
name:"."
forward-addr:223.5.5.5# 阿里云首选
forward-addr:223.6.6.6# 阿里云备用
# 可选:再加一个腾讯作为兜底
# forward-addr: 119.29.29.29

如果第一个服务器不可用,Unbound 会自动尝试下一个。

5. 解决端口 53 冲突

启动 Unbound 之前,先确认没有其他服务占用 53 端口(DNS 标准端口)。

Rocky Linux 默认启用的 systemd-resolved 通常会在 127.0.0.53:53 上监听一个本地 DNS stub。如果 53 端口已被占用,Unbound 将无法启动。

检查端口占用情况:

sudo ss -tulpn | grep :53

如果看到 systemd-resolved 占用了 53 端口,只需禁用其 DNS stub 监听器,同时保留其他系统功能:

sudo mkdir -p /etc/systemd/resolved.conf.d
echo -e "[Resolve]\nDNSStubListener=no" | sudo tee /etc/systemd/resolved.conf.d/no-stub.conf
sudo systemctl restart systemd-resolved

重启后再检查一次:

sudo ss -tulpn | grep :53

如果 53 端口已空闲,下一步就可以顺利启动 Unbound 了。

6.验证配置并启动服务

启动前先做语法检查,提前发现配置错误:

sudo unbound-checkconf

如果配置无误,会返回:

unbound-checkconf: no errors in /etc/unbound/unbound.conf

如果有报错,Unbound 通常会指出具体行号。修正后再次运行检查,直到无错误为止。

配置通过验证后,启动服务并设为开机自启:

sudo systemctl enable --now unbound

查看服务状态:

sudo systemctl status unbound

正常情况应显示 active (running):

● unbound.service - Unbound DNS server
     Loaded: loaded (/usr/lib/systemd/system/unbound.service; enabled)
     Active: active (running) since ...

如果启动失败,查看状态输出中的错误信息,或检查日志:

sudo journalctl -u unbound --no-pager

7. 防火墙放行 DNS 流量

如果启用了 firewalld,需要允许 DNS 入站流量,否则局域网内的客户端无法访问:

sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload

验证规则是否生效:

sudo firewallctl --list-services

你应该能看到 dns 出现在允许的服务列表中,例如:

cockpit dhcpv6-client dns ssh

至此,防火墙已配置完成,允许 Unbound 配置中授权的客户端发起 DNS 请求。

8. 验证 DNS 缓存是否生效

现在来验证 Unbound 是否真正在缓存 DNS 响应。在 DNS 服务器上,用 dig 直接指向 Unbound 查询一个域名:

dig haopython.com @192.168.1.50

关注输出中的 Query time 字段。第一次查询通常较慢,因为 Unbound 需要向上游 DNS 发起递归解析:

;; Query time: 68 msec
;; SERVER: 192.168.1.50
#53(192.168.1.50)

再执行一次同样的命令:

dig haopython.com @192.168.1.50

这次响应应该快得多,因为结果直接从缓存返回:

;; Query time: 0 msec
;; SERVER: 192.168.1.50#53(192.168.1.50)

实际查询时间因网络环境和上游 DNS 而异,但第二次查询通常明显快于第一次。从本地缓存返回时,0 ms 或 1 ms 很常见。

换几个域名再试试:

dig baidu.com @192.168.1.50
dig github.com @192.168.1.50

每个域名执行两次,对比 Query time。第一次走上游,第二次走缓存——这就是 DNS 缓存生效的最佳证明。

9. 配置客户端使用 Unbound DNS

DNS 服务器跑起来之后,最后一步是让客户端指向它。

如果使用 NetworkManager,将 Unbound 服务器(192.168.1.50)设为首选 DNS:

先列出可用连接:

nmcli connection show

记下活跃连接的名称(例如 "Wired connection 1"),然后执行:

sudo nmcli connection modify "Wired connection 1" ipv4.dns "192.168.1.50"
sudo nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes
sudo nmcli connection up "Wired connection 1"

这几条命令让客户端使用你的 Unbound 服务器解析 DNS,而不再依赖路由器或 DHCP 自动分配的 DNS。

查看 /etc/resolv.conf 确认配置:

cat /etc/resolv.conf

应该能看到:

nameserver 192.168.1.50

在客户端上测试解析:

dig baidu.com

输出中的 SERVER 字段应显示你的 Unbound 服务器:

;; SERVER: 192.168.1.50#53(192.168.1.50)

再测几个域名:

dig github.com
dig haopython.com

如果查询成功且 SERVER 指向 192.168.1.50,说明客户端已成功接入 Unbound。

从此以后,重复查询同一域名时,Unbound 会优先从缓存返回结果,减少查询延迟,降低对上游 DNS 的无效请求。

10. 日常运维与排错

以下 unbound-control 命令覆盖了日常维护的大部分场景:

命令用途
sudo unbound-control status
查看运行时间、版本号及查询响应状态
sudo unbound-control stats_noreset | grep total
查看总查询数和缓存命中数(不重置计数器)
sudo unbound-control dump_cache > /tmp/dns_cache_backup.txt
将完整缓存导出到文件,适合重启前备份
sudo unbound-control lookup haopython.com
查看某域名的解析来源及是否已缓存
sudo unbound-control flush haopython.com
清除单个域名的缓存记录
sudo unbound-control flush_zone haopythonlocal.com
清除某个区域下的所有缓存记录,适合内部 DNS 记录变更后不想等 TTL 过期的情况

# 常见故障排查

如果客户端报告无法解析任何域名,优先执行:

sudo journalctl -u unbound -f

绝大多数问题可归因于两类原因:

(1)访问控制问题:access-control 未包含客户端所在子网

(2)上游不可达:forward-zone 指向的上游 DNS 服务器在网络中无法访问

至此,已经在 Rocky Linux 10 上成功部署了 Unbound 作为本地 DNS 缓存解析器。

最新文章

随机文章