Unbound是NLnet Labs开发的开源递归DNS解析器,凭借出色的解析速度、严格的DNSSEC验证能力和较低的内存占用,成为自建DNS服务的热门选择。相比BIND那种功能全但配置繁重的软件,Unbound专注于递归解析这一件事,配置文件更简洁,安全漏洞也更少。这篇文章从安装入手,逐步讲清核心配置项的含义,带你搭出一套可用的递归DNS服务器。

一、递归解析与转发模式的区别
在动手配置之前,需要先理解Unbound的两种工作模式。第一种是纯递归模式,Unbound收到查询请求后,会从根服务器开始,逐级向下询问顶级域、权威服务器,最终拿到结果返回给客户端。这种模式的好处是结果直接来自权威源,可信度高,同时配合DNSSEC可以做完整性验证;缺点是首次查询延迟略高,不过有缓存之后后续查询会很快。
第二种是转发模式,Unbound把查询请求统一转发给上游DNS(比如运营商DNS或公共DNS),由上游完成递归,Unbound只做缓存。这种模式适合网络出口受限、无法直接访问根服务器的环境,响应速度取决于上游质量,且无法对上游结果做严格的DNSSEC验证。
两者可以在配置中共存,比如设置本地域名走内部服务器、其他查询走转发。理解了这一点,后面的配置参数就很好懂了。
二、安装与基础配置
以Debian和Ubuntu为例,直接用apt安装即可:
sudo apt update sudo apt install unbound -y systemctl status unbound
安装完成后,主配置文件位于/etc/unbound/unbound.conf。Debian系通常建议把自定义内容放到unbound.conf.d目录下,避免升级时被覆盖。创建一个自定义配置文件:
sudo vim /etc/unbound/unbound.conf.d/myunbound.conf
写入如下基础配置:
server:
# 监听的端口和地址,设为0.0.0.0表示接受任意网卡
interface: 0.0.0.0
port: 53
# 允许查询的网段,按实际内网调整
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/24 allow
# 开启日志,排障时有用,稳定后可改为0
verbosity: 1
use-syslog: yes
# 不返回版本信息,避免暴露细节
hide-identity: yes
hide-version: yes
# 开启DNSSEC验证(依赖内置的根信任锚)
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# 性能优化
num-threads: 2
msg-cache-size: 64m
rrset-cache-size: 128m
prefetch: yes其中access-control非常重要,默认Unbound只允许本机查询,如果不添加内网网段,其他机器的查询会被拒绝。修改后先检查语法再重启:
sudo unbound-checkconf sudo systemctl restart unbound
验证服务是否正常工作,用dig指定本机查询一个域名:
dig @127.0.0.1 www.example-ipipp.com
如果返回结果里status为NOERROR且带有答案记录,说明递归解析已经跑起来了。
三、本地解析记录与转发模式设置
很多内网场景需要把内部主机名解析到内网IP,Unbound通过local-data实现。在配置文件的server段中添加:
server:
local-zone: "home.lan." static
local-data: "nas.home.lan. IN A 192.168.1.10"
local-data: "printer.home.lan. IN A 192.168.1.20"local-zone声明了一个本地区域home.lan,static表示该区域内的域名全部以本地记录为准,查不到就直接返回NXDOMAIN,不会转发到公网。这既能解析内网服务,又避免了内网域名泄露到公网DNS。
如果需要转发模式,可以添加forward-zone段。比如把所有查询转发到公共DNS:
forward-zone:
name: "."
forward-addr: 223.5.5.5
forward-addr: 119.29.29.29
forward-first: no还可以只转发特定域名,比如内网中有一个独立的内部DNS服务器负责公司域名:
forward-zone:
name: "corp.example-ipipp.com."
forward-addr: 192.168.1.2这样配置后,corp.example-ipipp.com下的所有查询都会交给192.168.1.2处理,其余域名仍然走正常的递归解析,灵活性很高。
四、DNSSEC验证与常见问题排查
DNSSEC是Unbound的一大优势,它能验证域名返回的数据没有被篡改。只要配置了auto-trust-anchor-file,Unbound默认会对支持DNSSEC的域名做验证。验证方法很简单,查询一个故意损坏的记录:
dig @127.0.0.1 dnssec-failed.org
如果返回status为SERVFAIL,说明验证生效了,因为这个域名的DNSSEC签名本身就是坏的,Unbound正确地拒绝了被污染的数据。如果想看到详细的验证过程,可以临时把verbosity调到2,或者用unbound-control查看:
sudo unbound-control lookup www.example-ipipp.com
实际运维中常见的几个问题这里也提一下。第一是端口53被systemd-resolved占用,表现为Unbound启动失败或监听不上,可以用ss -lntup | grep 53确认,然后在/etc/systemd/resolved.conf中把DNSStubListener设为no并重启systemd-resolved。第二是UDP 53出网被防火墙拦截,纯递归模式就完全无法工作,此时只能改用转发模式。第三是客户端查询被拒绝,绝大多数情况是access-control没有放行客户端网段。
最后,建议在生产环境开启statistics-interval并定期用unbound-control stats_noreset查看缓存命中率和查询量,根据负载微调num-threads和缓存大小。配置得当的Unbound单机每秒可以处理上万次查询,对中小规模内网来说绰绰有余。