BIND9 9.18.39 配置参数详解

BIND9(实测 9.18.39-0ubuntu0.22.04.7,上游对照 9.20.29)named.conf 配置参数详解:options 与 zone 核心参数逐项实测,listen-on/allow-query/recursion/forwarders/dnssec-validation/notify/allow-transfer 每项改动经 named-checkconf→rndc reload→dig 闭环验证,含错误对照表。

BIND92026/10/20

BIND9 9.18.39 配置参数详解

目标:对 BIND9 主配置 named.conf 的 options 全局参数与 zone 局部声明核心参数逐项实测——每项参数按「改配置 → named-checkconf 校验 → rndc reload 生效 → dig 验证行为」闭环记录真实回显。实测环境 Ubuntu 22.04.4 LTS,bind9 1:9.18.39-0ubuntu0.22.04.7(jammy 仓库线,2026-10-20);ISC 上游当前稳定版为 9.20.29(isc.org/bind 实查),两者 options/zone 语句体系一致,本文结论适用于 9.18/9.20 双线。

一、环境信息

项目实测值
操作系统Ubuntu 22.04.4 LTS(jammy),x86_64,内核 6.8.0-138-generic
软件版本named/rndc/dig 均 9.18.39-0ubuntu0.22.04.7-Ubuntu(Extended Support Version)
服务形态named.service(systemd),运行用户 bind
配置目录/etc/bind(named 只读,AppArmor)/ /var/lib/bind(动态区)/ /var/cache/bind(缓存)
测试 zonelab.example(正解)+ 88.168.192.in-addr.arpa(反解),type master
上游版本对照9.20.29(Current Stable/ESV,2026-09 发布,2026-10-20 实查 isc.org/bind;jammy 可装 9.18.39 与上游 EOL 时间线差异见选型篇)

rndc 控制通道密钥文件 /etc/bind/rndc.key(安装时自动生成)的实测形态(secret 为实测样例展示,生产环境应保密):

key "rndc-key" {
        algorithm hmac-sha256;
        secret "53ADzUZ39Hpx18pZZy8d9zrJwI53K5Q8Zdm8ikMzoMc=";
};

二、配置文件体系与生效闭环

Debian/Ubuntu 的 named.conf 只做 include 组织:

include "/etc/bind/named.conf.options";   // 全局 options
include "/etc/bind/named.conf.local";     // 本机 zone 声明
include "/etc/bind/named.conf.default-zones"; // 根提示与 localhost 系列默认区

本篇所有实验共用同一套固定闭环,四步缺一不可:

1) 编辑 /etc/bind/named.conf.options 或 named.conf.local
2) named-checkconf            # 语法校验,无输出=通过
3) rndc reload                # 热加载,回显 "server reload successful"
4) dig @127.0.0.1 <域名>      # 行为验证

rndc reload 后 journal 会记录加载行为(实测):

ops named[1372912]: received control channel command 'reload'
ops named[1372912]: reload succeeded

三、options 核心参数逐项实测

3.1 listen-on:监听地址收敛

默认 named 监听本机所有接口(实测 ss -lunp 中 named 绑定了全部地址的 53 端口)。收敛到仅回环:

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on port 53 { 127.0.0.1; };
        listen-on-v6 { none; };
};

生效后验证(实测):

# named-checkconf
# rndc reload
server reload successful
# dig @127.0.0.1 www.lab.example +noall +answer
www.lab.example.        604800  IN      A       192.168.88.20
# dig @10.0.1.1 www.lab.example +time=2 +tries=1
;; connection timed out; no servers could be reached

127.0.0.1 应答正常、原监听的其他地址(10.0.1.1)超时不可达——listen-on 即时生效。listen-on-v6 { none; } 同理关闭 IPv6 监听,消除无 IPv6 出口环境下的 network unreachable resolving './NS/IN' 日志噪音。

3.2 allow-query:应答对象白名单

allow-query { 127.0.0.0/8; };

实测:允许网段内的客户端查询本机 zone 正常返回;白名单外的来源对本机数据的查询将被拒绝。它控制「谁能问我任何问题」,与控制「谁能从我这里递归」的 allow-recursion 是两层闸门。

3.3 recursion:递归开关

recursion no;

实测:关闭后对本机非权威域名(公网域名)直接拒绝:

# dig @127.0.0.1 www.baidu.com +noall +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 35780
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

同时本机权威 zone 应答不受影响(www.lab.example 仍 NOERROR)——纯权威模式上线的关键一档。日志显示该查询 flags: qr rd(无 ra,递归不可用)。

3.4 allow-recursion:递归白名单

recursion yes;
allow-recursion { 127.0.0.0/8; };

recursion yes 是总开关,allow-recursion 细化到来源网段;两者配合是「内网递归、外网权威」一体机的标准写法。白名单外来源递归查询返回 REFUSED。

3.5 forwarders / forward:转发模式

recursion yes;
allow-recursion { 127.0.0.0/8; };
forwarders { 223.5.5.5; };
forward only;

实测结果出乎直觉——rndc reload 成功,但 dig 返回 SERVFAIL:

# rndc reload
server reload successful
# dig @127.0.0.1 www.baidu.com +noall +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 42631
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

而直连转发器本身是通的(dig @223.5.5.5 www.baidu.com NOERROR)。journal 给出根因(实测逐行):

ops named[1372912]: DNS format error from 223.5.5.5#53 resolving baidu.com/DS for <unknown>: unrelated SOA hpvv...com in baidu.com authority section
ops named[1372912]: no valid RRSIG resolving 'baidu.com/DS/IN': 223.5.5.5#53
ops named[1372912]:   validating com/SOA: got insecure response; parent indicates it should be secure
ops named[1372912]: broken trust chain resolving 'www.baidu.com/A/IN': 223.5.5.5#53

结论:dnssec-validation auto(默认开启)要求向上游取证 DNSSEC 记录,而该转发器不返回 DNSSEC 数据,信任链断掉即 SERVFAIL。

3.6 dnssec-validation:与转发器的配套

forwarders { 223.5.5.5; };
forward only;
dnssec-validation no;

实测:关闭校验后同一查询立即恢复:

# dig @127.0.0.1 www.baidu.com +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51442
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
www.baidu.com.          1148    IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       64      IN      A       110.242.70.57

参数取值三档:yes(强制校验,失败即 SERVFAIL)/ auto(默认,用 managed-keys 自动维护根信任锚)/ no(不校验)。选型口诀:转发到支持 DNSSEC 的上游(如自建 Unbound 递归)保持 auto;转发到不回 DNSSEC 记录的公共解析器则显式 no,或换成支持的上游。

3.7 directory:zone 文件相对路径基准

directory "/var/cache/bind";

Ubuntu 默认把相对路径的 zone 文件锚定在 /var/cache/bind;本文 zone 用绝对路径 /etc/bind/...,不受影响。AppArmor 规则同时放开 /var/cache/bind 读写、/etc/bind 只读、/var/lib/bind 读写。

四、zone 声明核心参数实测

named.conf.local 中两个 master 区的完整实测声明:

zone "lab.example" {
    type master;
    file "/etc/bind/db.lab.example";
    notify no;
    allow-transfer { none; };
};

zone "88.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.88";
    notify no;
    allow-transfer { none; };
};

4.1 type master / file

type master(9.18 起文档口径写作 primary,rndc zonestatus 显示 type: primary)声明权威主区;file 指向 RFC 1035 格式的区数据文件。加载成功后的状态(实测):

# rndc zonestatus lab.example
name: lab.example
type: primary
files: /etc/bind/db.lab.example
serial: 2
nodes: 4
last loaded: Tue, 20 Oct 2026 07:45:24 GMT
secure: no
dynamic: no

serial 即 SOA 序号,每次手工改 zone 文件必须递增并 rndc reload,否则从区与缓存不会感知变更。

4.2 notify no

notify 默认 yes——master 区数据变更时向 NS 记录中的从服务器发 NOTIFY 通知。本实验无从区,显式 notify no 关闭通知,消除无谓的 NOTIFY 尝试日志;主从架构中应保持默认并配合 also-notify 指定额外通知目标。

4.3 allow-transfer { none; }

实测:不加该参数时 dig ... AXFR 可整区拖走;加上 none; 后:

# dig @127.0.0.1 lab.example AXFR
; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> @127.0.0.1 lab.example AXFR
; (1 server found)
;; global options: +cmd
; Transfer failed.

journal 同步记录拒绝(实测):

ops named[1372912]: client @0x7c6a14c081b8 127.0.0.1#36931 (lab.example): zone transfer 'lab.example/AXFR/IN' denied

公网权威区建议一律 allow-transfer { none; }(或仅放行从区 IP + TSIG)。

4.4 allow-update 与动态区的文件位置(AppArmor 坑)

给 zone 加 allow-update { 127.0.0.1; }; 开放动态更新后,用 nsupdate 加记录的实测结果取决于 zone 文件位置:

  • zone 文件在 /etc/bind(named 只读)——更新失败,journal 实测:
ops named[1372912]: client @0x7c69f800d088 127.0.0.1#42099: updating zone 'lab.example/IN': adding an RR at 'test1.lab.example' A 192.168.88.99
ops named[1372912]: /etc/bind/db.lab.example.jnl: create: permission denied
ops named[1372912]: client @0x7c69f800d088 127.0.0.1#42099: updating zone 'lab.example/IN': error: journal open failed: unexpected error

nsupdate 侧回显 update failed: SERVFAIL。

  • zone 文件移到 /var/lib/bind(AppArmor 对 named 读写开放)并把 file 指过去——更新成功(实测):
# nsupdate -v
> server 127.0.0.1
> zone lab.example
> update add test1.lab.example 300 IN A 192.168.88.99
> send
(rc=0)
# dig @127.0.0.1 test1.lab.example +noall +answer
test1.lab.example.      300     IN      A       192.168.88.99

动态更新会自动把 SOA serial 从 2 递增到 3 并落 journal(/var/lib/bind/db.lab.example.jnl),rndc zonestatus 的 dynamic 字段变为 yes。

五、校验与生效闭环汇总

步骤命令通过形态
语法校验named-checkconf无输出,rc=0
zone 校验named-checkzone lab.example /var/lib/bind/db.lab.examplezone lab.example/IN: loaded serial 3 + OK
热加载rndc reloadserver reload successful
行为验证dig @127.0.0.1 <域名>预期 status/answer
状态确认rndc zonestatus <zone>serial/dynamic/type 符合预期

六、常见错误对照表(实测原样回显)

报错根因解法
/tmp/badcheck.conf:9: missing ';' before 'allow-recursion'语句漏分号补分号,named-checkconf 会给出文件与行号
zone lab.example/IN: loading from master file /etc/bind/db.notexist failed: file not foundfile 路径错/文件未建核对路径,重跑 named-checkzone
/etc/bind/db.lab.example.jnl: create: permission denied动态区文件在 /etc/bind(AppArmor 只读)zone 文件迁 /var/lib/bind 并改 file 指向
broken trust chain resolving '.../A/IN': 223.5.5.5#53转发器不回 DNSSEC 记录 + validation 开启dnssec-validation no 或换支持 DNSSEC 的上游
rndc: 'freeze' failed: not dynamic对静态 master 区执行 freeze仅动态区(allow-update)支持 freeze/thaw
rndc: 'nocommand' failed: unknown commandrndc 子命令拼写错误rndc 无参数查看命令清单

七、参考链接