
OneUptime DNSSEC 监控实战从配置选项到 dig 底层实现的完整指南【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptimeDNSSECDomain Name System Security Extensions通过数字签名保证 DNS 应答的密码学完整性而签名失效、DS 委派缺失或权威服务器不同步都会导致验证型解析器向终端用户返回 SERVFAIL。本文基于 OneUptime 官方文档 dnssec-monitor.md英文对照版见 en/monitor/dnssec-monitor.md系统讲解 DNSSEC 监控器的创建流程、全部配置参数与监控判据并结合 Probe/Utils/Monitors/MonitorTypes/DnssecMonitor.ts 的源码实现说明每次探测背后的 dig 调用链、时间预算与在线判定逻辑帮助读者既会用、也懂其原理。一、DNSSEC 监控解决什么问题OneUptime 的 DNSSEC 监控器会周期性地对指定区域Zone执行完整的 DNSSEC 验证检查项覆盖 DNSKEY 记录、父区域中的 DS 委派、RRSIG 签名有效期、各解析器对 ADAuthenticated Data标志位的共识以及权威 Nameserver 之间的一致性。与常规 DNS/HTTP 监控不同DNSSEC 监控器验证的是从根区域一直到目标域名的完整信任链。文档列出的五大能力如下在解析器开始向用户返回 SERVFAIL 之前发现断裂的 DNSSEC 链——签名问题往往有窗口期监控可以提前暴露在区域签名密钥到期前收到告警——密钥轮换key rollover可能静默失败确认 DS 记录已在父区域正确发布——DS 缺失或 key tag 不匹配是常见的委派故障捕获权威 Nameserver 之间的分歧——典型场景是主/从服务器未同步确认验证型解析器确实为你的区域设置了 AD 标志——证明验证链路在真实解析器侧走通。二、创建 DNSSEC 监控器操作流程共 5 步进入 OneUptime 仪表盘的Monitors监控页面点击Create Monitor创建监控器监控类型选择DNSSEC填写要验证的 Zone域名按需配置 Resolver 列表与监控判据criteria。对应的数据结构定义在 Common/Types/Monitor/MonitorStepDnssecMonitor.ts其getDefault()给出了创建时的默认值——这与文档中高级设置表的默认列一一对应public static getDefault(): MonitorStepDnssecMonitor { return { domainName: , resolvers: [1.1.1.1, 8.8.8.8, 9.9.9.9], checkNameserverConsistency: true, signatureExpiryWarningDays: 7, timeout: 10000, retries: 3, }; }可以注意两点其一resolvers缺省即为1.1.1.1, 8.8.8.8, 9.9.9.9三个公共验证型解析器其二checkNameserverConsistency在源码默认值中为true即 Nameserver 一致性检查默认开启文档将其标注为非必填指的是它不是必填字段而非默认关闭。fromJSON()解析时还会做防御性处理若 JSON 中resolvers缺失或过滤后为空会回退到默认三解析器避免后续迭代空列表抛出异常导致监控静默失效。三、配置选项全解3.1 基本设置字段说明必填Zone域名要通过 DNSSEC 验证的区域例如example.com是Resolvers用于查询的验证型解析器逗号分隔列表例如1.1.1.1, 8.8.8.8, 9.9.9.9是Check Nameserver ConsistencyNameserver 一致性检查逐个直接查询各权威 Nameserver验证它们返回相同的 SOA 序列号否源码侧有两层输入校验均位于 DnssecMonitor.tsisValidHostname()要求 Zone 名称长度不超过 253且匹配^[a-zA-Z0-9](https://link.gitcode.com/i/0b9e95716defa4017340faafde0572cb)?$以字母数字开头结尾中间允许连字符和点。校验失败会直接返回Invalid domain name: zone的失败结果而不是发起任何查询isValidHostnameOrIP()用于校验每个 Resolver 与每个权威 NS 的名称接受 IPv4、IPv6 或合法主机名。任一 Resolver 非法即报Invalid resolver: value。若 Resolver 列表整体为空则返回No DNS resolvers are configured for this DNSSEC monitor.的失败响应——源码注释明确这是纵深防御设计宁可报告配置错误也不能让 TypeError 逃逸导致监控器什么都不产出。3.2 高级设置字段说明默认值Signature Expiry Warning签名到期预警天RRSIG 到期过滤器使用的默认阈值7Timeoutms每次 DNS 查询的等待时间10000Retries失败后的重试次数3这三个参数在源码中的实际作用值得展开Timeout 并非整个检查的总时长。一次 DNSSEC 检查由多条腿leg组成DNSKEY、父区 DS、RRSIG、每个 Resolver 一次 dig、再对每个权威 NS 各一次 dig。若每条腿都独立吃满完整的 per-query 超时面对无响应的解析器时整个检查可能持续数分钟。因此 DnssecMonitor.ts 引入了共享时间预算const DNSSEC_TOTAL_TIMEOUT_MULTIPLIER: number 3; private static createTimeBudget(perLegTimeoutMs: number): DnssecTimeBudget { return { perLegTimeoutMs: perLegTimeoutMs, deadlineAt: Date.now() perLegTimeoutMs * DNSSEC_TOTAL_TIMEOUT_MULTIPLIER, ranOutOfTime: false, }; }即一次尝试attempt的总时长上限为Timeout × 3默认 30 秒。nextLegTimeoutMs()在每次发起 dig 前取min(单腿超时, 剩余预算)预算耗尽后返回null调用方随即停止发起新查询。若因此有腿没有执行完最终结果会如实报告DNSSEC check did not finish within its overall budget of timeout×3 ms并标记isTimeout: true——源码注释解释得很清楚基于残缺数据去断言区域未签名或解析器分歧属于伪造的 DNSSEC 结论所以宁可报超时。这类超时失败也不会重试因为再试一次只会消耗同样长的预算。Retries 的语义是精确的。异常处理分支中的重试逻辑为if (options.currentRetryCount (options.retry ?? config.retries ?? 3)) { options.currentRetryCount; await Sleep.sleep(1000); return await DnssecMonitorUtil.query(config, options); }每次重试间隔 1 秒重试次数取调用方显式传入值、监控配置retries、或最终兜底 3。注释特别强调用??而非||调用方显式要求 0 次重试就是 0 次不会被默认值覆盖。此外优先级上步骤级options.timeout高于config.timeout两者皆无时才落到 10000ms。Signature Expiry Warning7 天是签名到期天数过滤器在仪表盘中展示/默认使用的阈值基准配合下文第四节的判据使用。四、监控判据六种检查类型与过滤条件监控判据criteria决定 Zone 被判定为 online、degraded 还是 offline。可用的检查类型check on共六种检查类型说明DNSSEC Chain Is ValidDNSSEC 链有效整条验证链根区域 → TLD → Zone正确解析DNSSEC DNSKEY Record ExistsDNSKEY 记录存在Zone 至少发布了 1 条 DNSKEY 记录DNSSEC DS Record Exists At Parent父区域存在 DS 记录父区域发布了与 Zone KSK 匹配的 DS 记录DNSSEC Signature Expires In Days签名到期天数距离最近的 RRSIG 签名过期还有多少天DNSSEC Resolver ConsensusAD 标志解析器共识每个被查询的解析器都返回 ADAuthenticated Data标志DNSSEC Nameservers Are ConsistentNameserver 一致所有权威 Nameserver 返回相同的 SOA 序列号过滤条件分两类对Chain Is Valid、DNSKEY Exists、DS Exists At Parent、Resolver Consensus、Nameservers Are Consistent五项条件为True条件成立或False条件不成立对Signature Expires In Days条件为数值比较大于、小于、大于等于≥、小于等于≤。判定的实现位于 Common/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.ts。isMonitorInstanceCriteriaFilterMet()对每个CheckOn分支返回一条人类可读的结论字符串判据命中或null未命中例如链有效命中 True 时返回DNSSEC chain is valid for domain.链无效命中 False 时返回DNSSEC chain validation failed for domain.。数值类判据则交给CompareCriteria.compareCriteriaNumbers()用daysUntilSignatureExpiry与阈值比较。测试文件 DnssecMonitorCriteria.test.ts 覆盖了关键边界包括探测响应缺失时对任何过滤器都返回 null不可判定即探测失败不会误触发判据。4.1 示例判据文档原表完整继承DNSSEC 链断裂时告警检查类型DNSSEC Chain Is Valid过滤条件False签名到期前预警检查类型DNSSEC Signature Expires In Days过滤条件Less Than小于值7捕获父区域缺失 DS委派断裂检查类型DNSSEC DS Record Exists At Parent过滤条件False检测解析器分歧检查类型DNSSEC Resolver ConsensusAD 标志过滤条件False捕获 Nameserver 脑裂split-brain检查类型DNSSEC Nameservers Are Consistent过滤条件False五、一次探测的底层流程源码级解析从源码可以还原每次探测的完整调用链均在 DnssecMonitor.ts 内底层通过execFile(dig, ...)执行系统 dig 命令并解析 stdout输入校验Zone 主机名校验、Resolver 列表非空与逐项 IP/主机名校验见 3.1 节DNSKEY 获取fetchDnskeysdig dnssec short zone DNSKEY resolver解析短格式输出flags protocol algo pubkey提取 flags 与算法号。解析到至少一条 DNSKEY 即认定isZoneSigned true父区 DS 获取fetchParentDsdig dnssec short zone DS resolver解析短格式keyTag algo digestType digest四字段存入parentDsRecords非空即isParentDsPresent trueRRSIG 获取fetchRrsigdig dnssec zone SOA不带short从 ANSWER SECTION 中挑出RRSIG记录按name TTL class RRSIG type algo labels origTtl expiration inception keyTag signer ...的列格式解析出覆盖类型、算法、签名者、key tag、生效与过期时间。dig 输出的时间戳是 UTC 的YYYYMMDDHHMMSS由parseDigTimestamp()转为 ISO 8601到期天数计算earliestRrsigExpiration()取所有 RRSIG 中最早的过期时间daysUntilSignatureExpiry floor((earliest - now) / 86400000)——即距离最近的签名过期还有几天逐 Resolver 共识检查checkResolvers对每个配置的 Resolver 执行dig dnssec nocdflag zone A resolver。nocdflag意味着不带 CDChecking Disabled位解析器会真实验证并在遇到 bogus 数据时 SERVFAIL。每个 Resolver 记录三项adFlagflags 中是否含 AD、servfailWhenValidating状态是否为 SERVFAIL、以及异常信息。全部 Resolver 的adFlag均为真才认定resolverConsensusAd trueNameserver 一致性检查checkNameserverConsistency由checkNameserverConsistency开关控制先dig short zone NS枚举权威 NS 列表再对每个 NS 直接查询dig dnssec norecurse zone SOA ns提取 SOA 记录第 6 列的序列号与该 NS 返回的 SOA RRSIG 过期时间。areNameserversConsistent()的判定规则是任何一台 NS 查询出错或缺少序列号即不一致否则要求所有序列号去重后size ≤ 1。这一条能抓到纯 DNSSEC 验证看不到的主从同步问题综合链有效性判定const isChainValid: boolean isZoneSigned isParentDsPresent rrsigs.length 0 resolverConsensusAd (daysUntilSignatureExpiry undefined || daysUntilSignatureExpiry 0);即五个条件同时满足存在 DNSKEY、父区存在 DS、拿到过 RRSIG、所有解析器都置 AD 标志、且最近签名尚未过期。所有中间结果都进入 DnssecMonitorResponse 结构并随探测响应持久化字段包括dnskeysDNSKEY 明细、parentDsRecordsDS 明细、rrsigsRRSIG 明细含earliestSignatureExpiration、resolverChecks逐解析器的 AD/SERVFAIL 记录、nameserverChecks逐 NS 的 SOA 序列号与 RRSIG 过期时间、isChainValid、responseTimeInMs以及每次尝试的probeAttempts明细。监控详情页的展示组件 DnssecMonitorView.tsx 即消费这些字段。时间预算行为本身由 DnssecMonitorTimeout.test.ts 专门验证。六、最佳实践文档原节完整继承使用多个公共解析器——默认1.1.1.1、8.8.8.8、9.9.9.9确保单个解析器故障不会造成误报。这也与源码中每个 Resolver 独立查询、全部返回 AD 才认定共识的实现呼应单点故障只会在共识判据上留痕而不会直接判链断裂。提前在到期前预警——建议在签名过期前 7 天配置 degraded 告警、前 2 天配置 offline 告警密钥轮换key rollover可能静默失败。监控每一个签名区域——包括 Apex 域名、已签名的子域、以及委派给其他运营方的区域。启用 Nameserver 一致性检查——它能发现纯 DNSSEC 验证遗漏的主/从同步问题前提是探针所在网络没有封锁对任意 IP 的出站 DNS 流量因为该检查需要直连各权威 NS 的 53 端口。七、延伸阅读路径关注点文件文档原文德语App/FeatureSet/Docs/Content/de/monitor/dnssec-monitor.md文档原文英语App/FeatureSet/Docs/Content/en/monitor/dnssec-monitor.md探测实现dig 调用、时间预算、重试Probe/Utils/Monitors/MonitorTypes/DnssecMonitor.ts步骤数据结构与默认值Common/Types/Monitor/MonitorStepDnssecMonitor.ts探测响应字段定义Common/Types/Monitor/DnssecMonitor/DnssecMonitorResponse.ts判据评估逻辑Common/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.ts判据单元测试Common/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts超时预算测试Probe/Tests/Utils/Monitors/MonitorTypes/DnssecMonitorTimeout.test.ts需要说明的适用前提探测节点上必须存在dig命令实现通过execFile调用系统二进制且 Nameserver 一致性检查要求出站 DNS 不被封禁。理解以上流程后读者既能按第三节完成监控器配置、按第四节落地五类典型告警判据也能在收到告警时依据DnssecMonitorResponse中的逐 Resolver、逐 NS 明细快速定位是签名过期、DS 委派缺失还是主从不同步。【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考