Yadifa 3.0.10 配置参数详解
Yadifa 3.0.10 的 yadifad.conf 配置参数逐项详解:main 全局 60 余项、control/nsid/rrl、日志体系、TSIG 与 ACL、primary/secondary 区域、DNSSEC 策略族,每个重点参数均给出修改-验证实测闭环与排障实录。
Yadifa 3.0.10 配置参数详解
目标:把 Yadifa 3.0.10 的
yadifad.conf讲透——配置文件体系结构、每个区块的参数语义与默认值、以及重点参数的"改配置→重载→验证"实测闭环。文中全部验证回显来自真实服务器(Ubuntu 22.04,yadifad 3.0.10-11788)实测。
一、环境信息
本文实测与参数来源说明:
- 软件版本:Yadifa 3.0.10(构建号 11788,源码编译安装于
/opt/yadifa,安装步骤见《Ubuntu 22.04 安装 Yadifa 3.0.10 指南》) - 操作系统:Ubuntu 22.04 LTS,GCC 11.4.0,OpenSSL 3.0.2
- 配置基线:
/opt/yadifa/etc/yadifad.conf(安装后为空文件,全量参数从零构建);官方样例对照物为源码发布件etc/yadifad.conf.example - 参数语义与默认值核对来源:v3.0.10 源码附带手册
doc/yadifad.conf.man(3.x 线参数全集)与官网下载页附带的 2.x 参考手册(YRM26.pdf,用于版本差异核对) - 验证工具:
dig(dnsutils 9.18.39)、yadifa管理客户端、yadifad -V - 实测涉及的服务器:单机(本机 127.0.0.1)与双机主从(主 10.89.60.2 / 从 10.89.60.3,
example.test区域)
二、配置体系总览
2.1 配置文件与区块结构
Yadifa 3.0.10 的服务端配置只有一个入口 yadifad.conf,由两类行构成:区块定界行(<区块名> ... </区块名>)与"参数名 值"行,# 开头为注释。一个完整的配置骨架如下(与 2.x 语法差异见 2.3):
<main> ... </main> # 全局参数(监听、路径、线程、访问控制默认值)
<control> ... </control> # 管理控制通道开关
<nsid> ... </nsid> # 名称服务器标识符(NSID)
<rrl> ... </rrl> # 响应速率限制
<channels> ... </channels> # 日志输出通道定义
<loggers> ... </loggers> # 日志通道与级别的绑定
<key> ... </key> # TSIG 密钥定义(可多次出现)
<acl> ... </acl> # 访问控制列表定义
<zone> ... </zone> # 区域定义(每区域一段,可多次出现)
<dnssec-policy>/<key-suite>/<key-template>/<key-roll>/<denial> # DNSSEC 策略族
include "keys.conf" # 按行内联引入其他配置文件
include 是逐行内联语义(不是 PHP 式的字符串拼接),实践中把 TSIG 密钥集中在 keys.conf 与主配置分离是最常见的组织方式——因为主/从服务器间往往只有密钥文件需要同步。
2.2 生效方式
改完配置有两种生效路径,本篇验证均基于两者:
- 整体重启:
systemctl restart yadifad(手工方式为杀进程后重新执行/opt/yadifa/sbin/yadifad); - 控制通道热重载:
yadifa ctrl cfgreload(重读主配置)与yadifa ctrl -q example.test zonecfgreload(重读区域配置),无需中断服务,命令细节见《Yadifa 3.0.10 常用 CLI 命令详解》。
2.3 版本语法差异(2.x 与 3.x)
混用网络资料时的第一注意事项(全部经实测验证):
| 差异点 | 2.4.x(Ubuntu 包) | 3.0.x(本文基线) |
|---|---|---|
| 主区域类型 | type master | type primary |
| 从区域类型 | type slave | type secondary |
| 从区域上游 | primary <ip>(亦接受 master) | primary <ip> port 53 key <keyname> |
| 策略化 DNSSEC | 无 | <dnssec-policy> 等策略族区块 |
| EDNS0 默认上限 | 1232 | 4096(样例配置值) |
⚠️ 实测排障:在 2.4.2 中写 type primary,区域静默不加载——启动无报错、日志无异常,但查询一律返回 REFUSED;换成 2.x 的 type master 后立即可查。反之在 3.0.10 中写 type master 会得到 CONFIG_PARSE_UNKNOWN_KEYWORD。找不到区域时先核对版本关键字。
三、<main> 全局参数详解
<main> 是配置的心脏,v3.0.10 手册收录约 60 个参数。按功能分组给出参数名、类型与默认值(均核对自手册),随后对重点参数逐项给出实测验证。
3.1 参数全集速查
守护与身份(类型 FLAG=开关,PATH=路径,INT=整数,FQDN=域名,ACL=访问列表):
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
daemon(别名 daemonize) | FLAG | on | 守护进程化;systemd 托管时配 --nodaemon 用 off 行为 |
chroot / chroot-path | FLAG / PATH | off | 启用后以 chroot-path 为根运行(需先备齐其中的 etc/var 结构) |
hostname(别名 hostname-chaos) | FQDN | 空 | hostname.bind CH TXT 查询的应答值 |
serverid(别名 serverid-chaos) | 字符串 | 空 | id.server CH TXT 查询的应答值 |
version(别名 version-chaos) | 字符串 | 空 | version.yadifa CH TXT 查询的应答值 |
user / group(别名 uid/gid) | 字符串 | root | 降权运行身份(systemd 服务建议非特权用户) |
cpu-count-override | INT | 0 | 覆盖自动探测的 CPU 数(0=自动) |
网络与监听:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
port(别名 server-port) | INT | 53 | 监听端口 |
listen | HOST 列表 | 0.0.0.0 | 监听地址(可列多个,如 listen 192.0.2.53, 2001:db8::53) |
do-not-listen | HOST 列表 | 空 | 从监听地址中排除的地址 |
network-model | ENUM | LAN | 收发缓冲模型:LOOPBACK/LAN/MAN/WAN/VERY_LARGE_REGION/HUGE_REGION |
edns0-max-size | INT | 4096 | EDNS0 UDP 载荷上限(2.x apt 包默认 1232) |
max-tcp-queries(别名 max-tcp-connections) | INT | 100 | TCP 并发查询上限 |
tcp-query-min-rate | INT | 0 | TCP 查询最低速率(字节/秒),防慢速连接占用 |
xfr-connect-timeout | SECONDS | 5 | 区域传输出站连接超时 |
路径与文件:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
logpath(别名 log-path) | PATH | 前缀下 var/log/yadifa | 日志根目录(channels 中的相对文件名相对此目录) |
pidfile(别名 pid-file) | PATH | 前缀下 var/run/yadifad.pid | PID 文件 |
datapath(别名 data-path) | PATH | 前缀下 var/zones | 区域数据根目录(zone 的 file 相对此目录) |
keyspath(别名 keys-path) | PATH | 前缀下 var/zones/keys | DNSSEC 密钥目录 |
xfrpath(别名 xfr-path) | PATH | 前缀下 var/zones/xfr | 区域传输/journal 目录 |
log-files-disabled | FLAG | off | 禁用全部日志文件输出 |
查询与日志行为:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
statistics | FLAG | off | 开启后按 statistics-max-period 周期向 statistics 通道输出统计行 |
statistics-max-period | SECONDS | 60 | 统计输出周期 |
queries-log-type | INT | 0 | 查询日志格式:1=详细格式(含标志位与客户端地址) |
log-unprocessable | FLAG | off | 记录无法处理的报文 |
answer-formerr-packets | FLAG | true | 对畸形报文回 FORMERR(关闭则静默丢弃) |
访问控制默认值(可被 zone 段覆盖):
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
allow-query | ACL | any | 允许发起查询的来源 |
allow-update | ACL | none | 允许 RFC 2136 动态更新的来源 |
allow-transfer | ACL | none | 允许 AXFR/IXFR 的来源(生产建议 TSIG key) |
allow-notify | ACL | none | 接受 NOTIFY 的来源(从服务器上配置) |
allow-update-forwarding | ACL | none | 允许更新转发的来源 |
allow-control | ACL | none | 允许使用控制通道(yadifa 客户端)的来源 |
hidden-primary(别名 hidden-master) | FLAG | off | 隐藏主角色(仅做传输源,不对外应答) |
区域传输重试族:axfr-retry-delay(默认 600s,首次拉取失败重试间隔)、axfr-retry-jitter(默认 180s 抖动)、axfr-retry-failure-delay-multiplier(默认 5,线性退避系数)、axfr-retry-failure-delay-max(默认 3600s 退避上限)、axfr-max-packet-size(4096 字节)、axfr-max-record-by-packet(0=不限)、axfr-compress-packets(true 压缩)、axfr-strict-authority(true,AA 位严格)。
线程与性能族:thread-affinity-base、thread-affinity-multiplier、thread-count-by-address、zone-download-thread-count、zone-load-thread-count、zone-store-thread-count、zone-unload-thread-count、worker-backlog-queue-size——3.x 引入的线程池细分控制,默认按 CPU 数自动分配(实测启动横幅 got 6 CPUs),小规格单区域部署无需调整。
3.2 身份三参数实测(hostname/serverid/version)
配置三者后通过 CH TXT 元查询验证:
dig @127.0.0.1 version.yadifa CH TXT +noall +answer
dig @127.0.0.1 hostname.bind CH TXT +noall +answer
dig @127.0.0.1 id.server CH TXT +noall +answer
实测回显:
version.yadifa. 0 CH TXT "3.0.10"
hostname.bind. 0 CH TXT "ns1.example.test"
id.server. 0 CH TXT "yadifad-ns1"
三个值分别来自 <main> 中的 version "3.0.10"、hostname "ns1.example.test"、serverid "yadifad-ns1"。运维实践:对外服务建议把 version 置空(不泄露具体版本),hostname/serverid 用于内部多节点区分。
💡 技术拓展:
*.bind与version.yadifa等 CH 类(CHAOS)查询源于 BIND 的传统——用特殊域名承载服务器元信息,NSID(见第五章)是它的 EDNS 扩展化替代。这三者与dig +nsid配合是排查"连到的到底是哪台服务器"的标准手段。
3.3 监听参数实测(port/listen)
默认监听 53 端口、地址 0.0.0.0,ss 验证:
ss -lunp | grep :53
实测回显(节选):
UNCONN 0 0 0.0.0.0:53 0.0.0.0:* users:(("yadifad",pid=60864,fd=8))
修改-验证闭环:把 port 改为 5353、listen 收窄到本机回环后重启,再 ss -lunp | grep 5353 可见 127.0.0.1:5353 监听且外部地址不再监听;dig @127.0.0.1 -p 5353 example.test SOA +short 应答正常。验证完改回 53。
3.4 EDNS0 上限实测(edns0-max-size)
配置 4096 时应答的 EDNS 载荷通告:
dig @127.0.0.1 example.test SOA +edns +noall +comments | grep EDNS
实测回显:
; EDNS: version: 0, flags:; udp: 4096
udp: 4096 即来自 edns0-max-size。数值取值区间 512-65535;对外服务若链路上无巨帧且中间设备不可靠,1232 是安全值(apt 包 2.4.2 的默认),内网高吞吐场景可放大。
3.5 查询日志与统计实测(queries-log-type/statistics)
queries-log-type 1 后,每条查询落 queries.log,实测样例行:
2026-10-26 04:59:05.851356 | 61249 | queries | queries | I | query [d13a] {+-E---} example.test. IN DNSKEY (127.0.0.1#51319)
格式解读:[d13a] 为报文属性位图,{+-E---} 依次为递归期望、鉴权数据、EDNS0 等 6 个标志位,随后是查询名/类/类型与 (来源IP#端口)。生产排障时开此参数能看到精确到秒级的查询流水,但也最耗磁盘,建议常态关闭、排障时开启。
statistics on 后每分钟输出一行计数(statistics.log 实测样例):
2026-10-26 05:22:00.844180 | 61249 | timer | stats | I | udp (in=13 qr=9 ni=0 up=0 dr=0 st=1819 un=0 rf=0) tcp (in=1 qr=0 ni=0 up=0 dr=0 st=0 un=0 rf=0 ax=0 ix=1 ov=0) udpa (OK=12 FE=0 SF=0 NE=0 NI=0 RE=1 XD=0 XR=0 NR=0 NA=0 NZ=0 BV=0 BS=0 BK=0 BT=0 BM=0 BN=0 BA=0 TR=0) tcpa (OK=0 FE=0 SF=0 NE=0 NI=0 RE=0 XD=0 XR=0 NR=0 NA=0 NZ=0 BV=0 BS=0 BK=0 BT=0 BM=0 BN=0 BA=0 TR=0) rrl (sl=0 dr=0)
关键计数:ax/ix 分别是完成的 AXFR/IXFR 次数(上例 ix=1 即一次增量传输),dr 为丢弃数,rrl (sl=0 dr=0) 是限速滑过/丢弃计数——做容量监控时抓这行最省事。
四、<control> 控制通道
控制通道是 yadifa 管理客户端与 yadifad 通信的入口,区块内只有一个参数:
| 参数 | 默认 | 说明 |
|---|---|---|
enabled | false | 开启控制通道(3.0.10 默认编译支持,无编译开关差异) |
开启后需在 <main> 中以 allow-control 指定允许的来源(通常指向一个仅含 TSIG key 的 ACL)。实测配置组合:
<main>
allow-control controller
</main>
<control>
enabled true
</control>
<acl>
controller key admin-key
</acl>
验证:yadifa ctrl logreopen 返回退出码 0 即通道畅通;用错误密钥访问则收到 NOTAUTH(实录见第十二章)。控制命令全集见《Yadifa 3.0.10 常用 CLI 命令详解》。
五、<nsid>
NSID(Name Server Identifier,RFC 5001)通过 EDNS 选项标识应答的服务器,区块两个参数:
| 参数 | 说明 |
|---|---|
ascii | 以 ASCII 文本指定 NSID(如 ns1-eu-west) |
hex | 以十六进制指定 NSID(两者只设其一) |
配置后 dig @10.89.60.2 . CH NSID +nsid 应在回复中带回该标识(多节点负载均衡时用于确认命中节点)。实测环境单节点未启用该区块,留作多节点扩展项。
六、<rrl> 响应速率限制
RRL 用于抑制 DNS 放大攻击——同一网段来源在窗口期内超量的"相似应答"会被滑过(TRUNCATE)或丢弃。v3.0.10 支持的全部参数:
| 参数 | 默认 | 说明 |
|---|---|---|
responses-per-second | 10 | 每"前缀组"每秒最多应答数 |
errors-per-second | 5 | 每秒最多错误应答(NXDOMAIN/SERVFAIL)数 |
slip | 2 | 每 slip 个被拦应答放行 1 个并置 TC 位(让合法客户端转 TCP 重试) |
log-only | FLAG | off |
ipv4-prefix-length | 24 | IPv4 按此前缀长度分组计数 |
ipv6-prefix-length | 64 | IPv6 同上 |
exempt-clients | ACL | 豁免来源(如监控探针) |
enabled | FLAG | off |
min-table-size | 512 | 表初始尺寸 |
max-table-size | 4096 | 表上限(条目满时新来源不计数) |
window | 1 | 计数窗口秒数 |
统计行为可在 statistics.log 的 rrl (sl= dr=) 段观察(3.5 节实测样例行)。对外权威服务建议启用 responses-per-second 15 + slip 2 的保守组合,并用 log-only on 过渡一周后再实切。
💡 技术拓展:放大攻击指攻击者伪造源地址向权威服务器发起查询,利用"小请求大应答"的记录(如 ANY、大 TXT、DNSSEC 签名区)把流量放大数倍打向受害者。RRL 的核心思想是按"来源前缀+应答相似度"限流,slip 机制则保证真实递归服务器能通过 TC 位降级到 TCP 恢复正常查询。
七、<channels> 与 <loggers> 日志体系
Yadifa 日志是"通道(channel)→ 日志源(logger)"两级模型:<channels> 定义"写到哪"(文件/syslog/STDERR/STDOUT 及权限),<loggers> 定义"谁写到哪"(八类日志源 × 级别 × 输出通道组合)。
7.1 <channels> 输出通道
实测采用的八文件配置(每行格式:通道名 文件名 权限):
<channels>
database database.log 0644
dnssec dnssec.log 0644
server server.log 0644
statistics statistics.log 0644
system system.log 0644
zone zone.log 0644
queries queries.log 0644
all all.log 0644
stderr STDERR
stdout STDOUT
</channels>
说明:文件名相对 <main> 的 logpath;STDERR/STDOUT 是保留字(输出到进程对应流,systemd --nodaemon 模式下由 journald 收集);权限建议 0640 并配 logrotate。
7.2 <loggers> 日志源绑定
八类日志源:database(区域数据加载)、dnssec(签名与密钥)、server(进程与传输)、stats(统计)、system(系统级)、zone(区域事件)、queries(查询流水)。每行格式:日志源 级别集 输出通道[,通道...]:
<loggers>
database prod database,all
dnssec prod dnssec,all
server prod server,all
stats prod statistics
system prod system,all
zone prod zone,all
queries prod queries
</loggers>
级别集与日志级别(从高到低):PROD(生产级,即 INFO 及以上)、DEBUG-DEBUG7(7 档调试)、NOTICE/WARNING/ERR/CRIT/ALERT/EMERG、ALL(全部)。排障临时升档示例:system DEBUG3 system,all 重启后 system.log 会输出到模块函数级——排障完成务必降回,DEBUG 级日志量极大。
7.3 日志文件实测全貌
八通道配置下的日志目录(实测 ls /opt/yadifa/var/log/yadifa/):
all.log
database.log
dnssec.log
queries.log
server.log
statistics.log
system.log
zone.log
八、<key> 与 <acl>
8.1 <key> TSIG 密钥
| 参数 | 说明 |
|---|---|
name | 密钥名(传输/管理命令引用它的句柄) |
algorithm | TSIG 算法:hmac-md5 / hmac-sha1 / hmac-sha224 / hmac-sha256 / hmac-sha384 / hmac-sha512 |
secret | base64 编码的密钥材料 |
实测配置(两把 hmac-sha256 密钥:管理通道与主从传输各一把):
<key>
name admin-key
algorithm hmac-sha256
secret nRq+K4vp0w8/lZAwaOiAH+P3utxqu3bc0T/JSUQ5qLU=
</key>
⚠️ 实测排障(本篇第一大坑):secret 必须是合法 base64——总长度为 4 的倍数。手写凑数串(32 字符 + == 尾)触发:
error: reading configuration: PARSEB64_ERROR
config error: /opt/yadifa/etc/keys.conf: 5: '</key>': PARSEB64_ERROR
生成合法密钥的正确姿势:openssl rand -base64 32(输出 44 字符,天然合法)。密钥名在服务器间必须一致;secret 一致才能完成认证。
8.2 <acl> 访问控制列表
<acl> 定义可复用的命名访问组,成员既可以是 IP/网段也可以是 TSIG key 名(混合列表时按序匹配):
<acl>
transferer key primary-secondary
controller key admin-key
trusted-nets 10.89.60.0/24
</acl>
引用点:<main> 的 allow-* 族与 <zone> 段的 allow-* 均可引用 ACL 名或使用内联的 any/none/key <name>/网段描述符。生效顺序:zone 段 > main 段。
九、<zone> 区域参数详解
每个区域一个 <zone> 段。按角色分两组给参数与实测。
9.1 primary(主区域)参数与实测
主区域核心配置(实测在跑的完整段):
<zone>
type primary
domain example.test
file primaries/example.test.zone
allow-transfer key primary-secondary
allow-update none
dnssec-policy "test-policy"
</zone>
| 参数 | 说明 |
|---|---|
type | primary(3.x)/master(2.x) |
domain | 区域名(须与 zone 文件中的 SOA 一致) |
file(别名 file-name) | 区域文件,相对 datapath |
drop-before-load | FLAG,重载时先卸旧版本再加载(大区域减少双份内存) |
journal-size-kb | 主区域更新日志上限 |
notifies(别名 also-notify/notify) | 额外 NOTIFY 目标列表(从服务器清单之外再通知谁) |
notify-auto | FLAG,自动向所有从区域发 NOTIFY |
dnssec-mode(别名 dnssec) | on/off——手工签名开关(与 dnssec-policy 二选一) |
dnssec-policy | 引用策略族区块 id(见第十章,自动签名) |
maintain-dnssec | FLAG,让服务端在动态更新时维护已有签名 |
allow-transfer / allow-update | 区域级 ACL 覆盖 |
allow-transfer 修改-验证闭环(安全加固最常用操作):配置为 key primary-secondary 时,无 TSIG 的全量传输被拒:
dig @10.89.60.2 example.test AXFR +noall +answer 2>&1 | head -3
实测回显:
; Transfer failed.
带正确 TSIG key 的同一查询成功回出全区域 11 条记录(应答含 SOA、6 条 A、2 条 NS、1 条 MX、1 条 CNAME 及 SOA 续行,逐行回显见《Yadifa 3.0.10 常用 CLI 命令详解》第九章)。把值改为 none 再验证则两种方式均被拒——这一加一减即为区域级 ACL 的闭环验证。
9.2 secondary(从区域)参数与实测
从区域核心配置(实测从服务器在跑的完整段):
<zone>
type secondary
domain example.test
file secondaries/example.test.zone
primary 10.89.60.2 port 53 key primary-secondary
allow-notify 10.89.60.2
</zone>
| 参数 | 说明 |
|---|---|
type | secondary(3.x)/slave(2.x) |
primaries(别名 primary/masters/master) | 上游主服务器列表(可多个,支持 ip port N key <name>) |
multiprimary-retries(别名 multimaster-retries) | 多主轮询重试次数 |
true-multiprimary(别名 true-multimaster) | FLAG,多主时严格按 SOA 判新 |
no-primary-updates(别名 no-master-updates) | FLAG,忽略上游 SOA 过旧告警 |
allow-notify | 接受哪些来源的 NOTIFY |
notify-retry-count / notify-retry-period / notify-retry-period-increase | NOTIFY 重试次数/间隔/递增 |
journal-size-kb | 增量日志(IXFR 源)上限 |
⚠️ 实测排障(allow-notify 的 key 陷阱):最初给从服务器配置 allow-notify key primary-secondary(期望 NOTIFY 也走 TSIG 认证),主服务器 reload 发出 NOTIFY 后从服务器拒绝同步,zone.log 实测记录:
notify: secondary: example.test.: 10.89.60.2#34447: not authorised
结论:NOTIFY 报文不携带 TSIG,allow-notify 应配 IP/网段 ACL;TSIG 的正确位置是 primary 行(保护 AXFR/IXFR 传输本身)。改为 allow-notify 10.89.60.2 后,主服务器 reload + notify,从服务器数秒内完成同步——server.log 实测记录:
secondary: example.test.: got AXFR from primary at 10.89.60.2#53, serial is 2026102603
从服务器 DNSSEC 签名后的区域同步验证(DNSKEY 与 RRSIG 一并到达,实测):
dig @10.89.60.3 example.test DNSKEY +noall +answer | cut -c1-90
实测回显(节选):
example.test. 86400 IN DNSKEY 256 3 8 [key id = 54354]
example.test. 86400 IN DNSKEY 257 3 8 [key id = 47629]
9.3 区域数据落盘位置实测
从区域加载后数据实际写入 xfrpath(journal 文件,数字命名)而非 file 指定的文件(该文件仅在手工放置初始副本时使用)——实测 ls /opt/yadifa/var/zones/xfr/ 有以区域命名的 journal 条目、secondaries/ 目录为空。备份从区域时抓 xfrpath 目录。
十、DNSSEC 策略族(dnssec-policy / key-suite / key-template / key-roll / denial)
3.x 的自动 DNSSEC 由五个区块组成,实测用到的完整定义:
<dnssec-policy>
id "test-policy"
description "Minimal RSA policy for example.test"
denial nsec
key-suite "zsk-1024"
key-suite "ksk-2048"
</dnssec-policy>
<key-suite>
id "zsk-1024"
key-template "zsk-rsa-sha256-1024"
key-roll "never-roll"
</key-suite>
<key-suite>
id "ksk-2048"
key-template "ksk-rsa-sha256-2048"
key-roll "never-roll"
</key-suite>
<key-template>
id "zsk-rsa-sha256-1024"
algorithm RSASHA256
size 1024
</key-template>
<key-template>
id "ksk-rsa-sha256-2048"
ksk 1
algorithm RSASHA256
size 2048
</key-template>
<key-roll>
id "never-roll"
generate 0 0 1 1 * *
publish 0 1 1 1 * *
activate 0 2 1 1 * *
inactive 0 3 1 1 * *
remove 0 4 1 1 * *
</key-roll>
各区块职责与参数:
| 区块 | 关键参数 | 职责 |
|---|---|---|
<key-template> | algorithm(RSASHA256/RSASHA512/ECDSAP256SHA256 等)、size、ksk(1=KSK) | 单把密钥的规格 |
<key-suite> | key-template、key-roll | 一套 KSK+ZSK 组合及其滚动计划 |
<key-roll> | generate/publish/activate/inactive/remove 五条 cron 风格六字段时间表(分 时 日 月 周 周) | 密钥全生命周期排程 |
<dnssec-policy> | denial(nsec / nsec3 / nsec3-optout 关键字或 <denial> 区块 id)、一个或多个 key-suite | 区域级签名策略总装 |
<denial> | type(NSEC/NSEC3)、NSEC3 的 salt/iterations/optout 参数 | 否认存在证明的实现方式 |
⚠️ 实测排障(key-roll 必填):<key-suite> 只配 key-template 不配 key-roll 时启动报错(实测回显):
error: config: key-suite: ksk-2048: key-roll not set
error: reading configuration: POLICY_KEY_SUITE_UNDEFINED
补上 key-roll 引用后正常。策略虽可复用 never-roll(每年仅 1 月 1 日动作的时间表,等价于不滚动),但定义必须存在。
签名生效验证:zone 段引用 dnssec-policy "test-policy" 重启后,keyspath 目录自动生成密钥(实测 ls /opt/yadifa/var/zones/keys/):
Kexample.test.+008+47629.key
Kexample.test.+008+47629.private
Kexample.test.+008+54354.key
Kexample.test.+008+54354.private
命名规则 K<zone>.+<算法号>+<keytag>:008 即 RSASHA256,47629 的 DNSKEY flag 为 257(KSK)、54354 为 256(ZSK)。dig 验证签名链(实测,DNSKEY 行 100 列截断展示):
dig @127.0.0.1 example.test DNSKEY +noall +answer | cut -c1-100
dig @127.0.0.1 www.example.test A +dnssec +noall +answer | grep RRSIG | cut -c1-130
dig @127.0.0.1 example.test NSEC +noall +answer
实测回显:
example.test. 86400 IN DNSKEY 256 3 8 AwEAAamkaQgEHISWVa0U43v+/cD/45E2+cViNQ0oTqGwUUl0BNybn9+G zV6q
example.test. 86400 IN DNSKEY 257 3 8 AwEAAcQW4GUzwE/ve4ZBmF8lzw/GW17d8IK4YAcy/onLuKIdgINSaqgy 466I
www.example.test. 86400 IN RRSIG A 8 3 86400 20261124052511 20261025050310 54354 example.test. LlwCuIn5wccy4wY4+4OndNOe8kYdG07GPl2
example.test. 86400 IN NSEC api.example.test. A NS SOA MX RRSIG NSEC DNSKEY
同时观察 dnssec.log(实测节选)确认密钥生命周期被策略接管:
2026-10-26 04:58:22.431825 | 61249 | zone sig | dnssec | I | dnssec-policy: example.test.: key Kexample.test.+008+47629/257 generated from 2026-01-01 00:00:00: created at 2026-10-26 04:58:22, publish at 2026-01-01 01:00:00, activate at 2026-01-01 02:00:00, inactive at 2027-01-01 03:00:00, delete at 2027-01-01 04:00:00
2026-10-26 04:58:22.431825 | 61249 | zone sig | dnssec | I | zone is NSEC, chain is probably incomplete
2026-10-26 04:58:22.431825 | 61249 | zone sig | dnssec | I | zone is NSEC
注意两点:签名后 SOA serial 会被自动推进(实测从手工维护的 2026102603 推进到 2026102606,DNSSEC 管理会占用 serial 低位做版本管理);RRSIG 的有效期由 <main> 的 sig-validity-interval(默认 30 天)、sig-validity-jitter、sig-validity-regeneration 三个参数控制。
十一、修改-验证闭环实战
三个最典型的"改配置"场景,给出完整的操作-验证链(可作变更模板)。
11.1 热重载区域(不重启服务)
场景:区域文件加了记录,要生效且不中断服务。先改文件(serial 手工 +1):
sed -i "s/2026102602/2026102603/; /api IN CNAME www.example.test./a\\docs IN A 10.89.60.30" \
/opt/yadifa/var/zones/primaries/example.test.zone
经控制通道重载并验证:
yadifa ctrl -q example.test reload
dig @127.0.0.1 docs.example.test A +noall +answer
实测回显:
docs.example.test. 86400 IN A 10.89.60.30
11.2 通知从服务器并确认增量同步
主服务器侧触发:
yadifa ctrl -q example.test notify
从服务器侧验证(主从配置见第九章,实测数秒内完成):
dig @10.89.60.3 news.example.test A +noall +answer
dig @10.89.60.3 example.test SOA +noall +answer
实测回显:
news.example.test. 86400 IN A 10.89.60.40
example.test. 86400 IN SOA ns1.example.test. admin.example.test. 2026102603 10800 3600 604800 86400
SOA serial 与主服务器一致即为同步完成;过程中 server.log 的 got AXFR/IXFR 行可佐证传输类型。
11.3 开启 DNSSEC 自动签名
操作链:粘贴第十章策略区块 → zone 段加 dnssec-policy "test-policy" → 重启服务 → 三项验证(keys 目录出现 .key/.private、dig DNSKEY 出现 256/257 两条、dig +dnssec 应答带 RRSIG)→ 回滚即从 zone 段删掉 dnssec-policy 行重启(已有签名数据随区域重载自动剥离,serial 回到手工管理)。
十二、常见配置错误与排障实录
以下 8 个错误全部在实测中真实发生或验证过,按"现象 → 原因 → 处置"给出:
E1:PARSEB64_ERROR(keys.conf 的 </key> 行)
现象见 8.1。原因:TSIG secret 非法 base64。处置:openssl rand -base64 32 重新生成。
E2:CONFIG_PARSE_UNKNOWN_KEYWORD at <zone名>(yadifa 客户端)
现象:yadifa ctrl reload example.test 报 command line: CONFIG_PARSE_UNKNOWN_KEYWORD at example.test。原因:ctrl 命令的位置参数不走裸参数位,必须用 -q 传递。处置:yadifa ctrl -q example.test reload。querylog 同理(yadifa ctrl -q disable querylog)。
E3:控制命令返回 NOTAUTH
现象:command to 127.0.0.1#53 failed: NOTAUTH。原因:TSIG 认证失败——密钥不一致或命令行 -y 指定的密钥与配置文件中同名密钥冲突(后者还会先报 TSIG_DUPLICATE_REGISTRATION)。处置:核对两侧 secret,或统一走配置文件引用(-K <name>)。
E4:从服务器收到 NOTIFY 但 not authorised
现象与处置见 9.2:allow-notify 配 TSIG key 无效(NOTIFY 不带签名),改配主服务器 IP。
E5:error: yadifad already running with pid: xxx + PID_LOCKED
原因:上次进程异常退出后 pidfile 残留(或旧进程未死)。处置:确认无存活进程后 rm -f /opt/yadifa/var/run/yadifad.pid 再启动;systemd 托管可避免。
E6:key-roll not set / POLICY_KEY_SUITE_UNDEFINED
现象见第十章:key-suite 缺 key-roll 引用。处置:补 key-roll 行(可用 never-roll 形态)。
E7:区域静默不加载,查询 REFUSED
原因:2.x 配置用了 3.x 关键字(type primary 在 2.4.2 中不识别,区域被跳过且日志无错误)。处置:按 2.3 对照表核对版本关键字;排查时先看 zone.log 有无该区域的加载记录。
E8:启动告警 max_secondary_tcp_queries higher than max_tcp_queries (100)
无害告警:默认 TCP 并发 100 时从区域并发参数相形见绌。处置:调大 max-tcp-queries(如 200)即可消除;实测带此告警时主从传输与查询均正常。
十三、参考链接
- 官网下载页(含 2.x 线参考手册 YRM26.pdf 与校验文件):https://www.yadifa.eu/download.html
- GitHub 仓库(v3.0.10 源码与
doc/yadifad.conf.man、etc/yadifad.conf.example):https://github.com/yadifa/yadifa - v3.0.10 发布标签:https://github.com/yadifa/yadifa/releases/tag/v3.0.10
- RFC 5001(NSID)、RFC 8499(DNS 术语,primary/secondary 口径):IETF 官方文本
- 站内同专栏:《Yadifa 3.0.10 介绍与选型指南》(架构与选型)、《Ubuntu 22.04 安装 Yadifa 3.0.10 指南》(安装与首个区域)、《Yadifa 3.0.10 常用 CLI 命令详解》(yadifa ctrl 与 dig 实战)
- 站内对照阅读:《BIND9 9.18.39 配置参数详解》(named.conf 对照)、《Knot DNS 3.6.1 常用 CLI 命令与工具详解》