Yadifa 3.0.10 配置参数详解

Yadifa 3.0.10 的 yadifad.conf 配置参数逐项详解:main 全局 60 余项、control/nsid/rrl、日志体系、TSIG 与 ACL、primary/secondary 区域、DNSSEC 策略族,每个重点参数均给出修改-验证实测闭环与排障实录。

YadifaDNS服务器网络2026/10/26

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 mastertype primary
从区域类型type slavetype secondary
从区域上游primary <ip>(亦接受 master)primary <ip> port 53 key <keyname>
策略化 DNSSEC无<dnssec-policy> 等策略族区块
EDNS0 默认上限12324096(样例配置值)

⚠️ 实测排障:在 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)FLAGon守护进程化;systemd 托管时配 --nodaemon 用 off 行为
chroot / chroot-pathFLAG / PATHoff启用后以 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-overrideINT0覆盖自动探测的 CPU 数(0=自动)

网络与监听:

参数类型默认说明
port(别名 server-port)INT53监听端口
listenHOST 列表0.0.0.0监听地址(可列多个,如 listen 192.0.2.53, 2001:db8::53)
do-not-listenHOST 列表空从监听地址中排除的地址
network-modelENUMLAN收发缓冲模型:LOOPBACK/LAN/MAN/WAN/VERY_LARGE_REGION/HUGE_REGION
edns0-max-sizeINT4096EDNS0 UDP 载荷上限(2.x apt 包默认 1232)
max-tcp-queries(别名 max-tcp-connections)INT100TCP 并发查询上限
tcp-query-min-rateINT0TCP 查询最低速率(字节/秒),防慢速连接占用
xfr-connect-timeoutSECONDS5区域传输出站连接超时

路径与文件:

参数类型默认说明
logpath(别名 log-path)PATH前缀下 var/log/yadifa日志根目录(channels 中的相对文件名相对此目录)
pidfile(别名 pid-file)PATH前缀下 var/run/yadifad.pidPID 文件
datapath(别名 data-path)PATH前缀下 var/zones区域数据根目录(zone 的 file 相对此目录)
keyspath(别名 keys-path)PATH前缀下 var/zones/keysDNSSEC 密钥目录
xfrpath(别名 xfr-path)PATH前缀下 var/zones/xfr区域传输/journal 目录
log-files-disabledFLAGoff禁用全部日志文件输出

查询与日志行为:

参数类型默认说明
statisticsFLAGoff开启后按 statistics-max-period 周期向 statistics 通道输出统计行
statistics-max-periodSECONDS60统计输出周期
queries-log-typeINT0查询日志格式:1=详细格式(含标志位与客户端地址)
log-unprocessableFLAGoff记录无法处理的报文
answer-formerr-packetsFLAGtrue对畸形报文回 FORMERR(关闭则静默丢弃)

访问控制默认值(可被 zone 段覆盖):

参数类型默认说明
allow-queryACLany允许发起查询的来源
allow-updateACLnone允许 RFC 2136 动态更新的来源
allow-transferACLnone允许 AXFR/IXFR 的来源(生产建议 TSIG key)
allow-notifyACLnone接受 NOTIFY 的来源(从服务器上配置)
allow-update-forwardingACLnone允许更新转发的来源
allow-controlACLnone允许使用控制通道(yadifa 客户端)的来源
hidden-primary(别名 hidden-master)FLAGoff隐藏主角色(仅做传输源,不对外应答)

区域传输重试族: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 通信的入口,区块内只有一个参数:

参数默认说明
enabledfalse开启控制通道(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-second10每"前缀组"每秒最多应答数
errors-per-second5每秒最多错误应答(NXDOMAIN/SERVFAIL)数
slip2每 slip 个被拦应答放行 1 个并置 TC 位(让合法客户端转 TCP 重试)
log-onlyFLAGoff
ipv4-prefix-length24IPv4 按此前缀长度分组计数
ipv6-prefix-length64IPv6 同上
exempt-clientsACL豁免来源(如监控探针)
enabledFLAGoff
min-table-size512表初始尺寸
max-table-size4096表上限(条目满时新来源不计数)
window1计数窗口秒数

统计行为可在 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密钥名(传输/管理命令引用它的句柄)
algorithmTSIG 算法:hmac-md5 / hmac-sha1 / hmac-sha224 / hmac-sha256 / hmac-sha384 / hmac-sha512
secretbase64 编码的密钥材料

实测配置(两把 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>
参数说明
typeprimary(3.x)/master(2.x)
domain区域名(须与 zone 文件中的 SOA 一致)
file(别名 file-name)区域文件,相对 datapath
drop-before-loadFLAG,重载时先卸旧版本再加载(大区域减少双份内存)
journal-size-kb主区域更新日志上限
notifies(别名 also-notify/notify)额外 NOTIFY 目标列表(从服务器清单之外再通知谁)
notify-autoFLAG,自动向所有从区域发 NOTIFY
dnssec-mode(别名 dnssec)on/off——手工签名开关(与 dnssec-policy 二选一)
dnssec-policy引用策略族区块 id(见第十章,自动签名)
maintain-dnssecFLAG,让服务端在动态更新时维护已有签名
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>
参数说明
typesecondary(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-increaseNOTIFY 重试次数/间隔/递增
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)即可消除;实测带此告警时主从传输与查询均正常。

十三、参考链接