资讯详情

Zeek DNS 日志增强:如何将 Authoritative 与 Additional 响应纳入 dns.log(auth-addl 脚本深度解析)

📅 2026/10/10 1:54:19 | 华诺云谱 👁 阅读
Zeek DNS 日志增强:如何将 Authoritative 与 Additional 响应纳入 dns.log(auth-addl 脚本深度解析)
网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载导读Zeek 的 DNS 分析器默认只把 Answer 区段以及部分查询元数据写入 dns.log而响应报文中的权威Authoritative与附加Additional区段默认被跳过。本文围绕策略脚本 auth-addl.zeek讲解如何开启这两类响应的记录、其底层事件与解析机制、相关控制开关以及必须警惕的性能代价帮助你在安全分析需要完整 DNS 上下文、但链路负载可控的场景下正确使用这一能力。一、脚本定位补全 DNS 日志中被默认跳过的区段一个标准的 DNS 响应报文由四个区段组成Question问题、Answer回答、Authority权威即授权信息和 Additional附加如附加记录、EDNS 信息等。Zeek 的 DNS 分析器默认只对 Answer 区段进行深入处理原因很直接——权威与附加记录数量庞大、价值密度低逐条解析会显著增加 CPU 开销。这反映在基座脚本 scripts/base/init-bare.zeek 中定义的两个全局开关上## If true, all DNS AUTH records are skipped. global dns_skip_all_auth T redef; ## If true, all DNS ADDL records are skipped. global dns_skip_all_addl T redef;也就是说默认情况下 Zeek 会跳过所有权威记录和附加记录的处理。策略脚本policy/protocols/dns/auth-addl.zeek的作用就是显式地把这两个开关重新定义为F并让解析器为每个权威/附加响应生成事件、最终写入 dns.log 的两个新字段。原文档doc/scripts/policy/protocols/dns/auth-addl.zeek.rst给出了明确的定位说明命名空间NamespaceDNS依赖导入Importsbase/protocols/dns/main.zeek性能警告脚本会引发严重开销severe overhead因为所有权威与附加响应都需要生成事件不推荐在重负载链路上使用。二、脚本核心实现逐行解析完整源码位于 scripts/policy/protocols/dns/auth-addl.zeek共 45 行逻辑非常紧凑2.1 加载依赖并打开开关load base/protocols/dns/main redef dns_skip_all_auth F; redef dns_skip_all_addl F; module DNS;load base/protocols/dns/main保证 DNS 分析器与基础事件处理已就绪随后通过redef把两个全局跳过开关改写为F通知底层解析器权威区和附加区都需要逐条解析并触发事件。2.2 扩展日志记录结构 DNS::Infoexport { redef record Info { ## Authoritative responses for the query. auth: set[string] log optional; ## Additional responses for the query. addl: set[string] log optional; }; }这里向DNS::Info记录追加两个字段原文档中定义为 Redefinitions / New Fields新字段类型属性含义authset[string]logoptional当前查询的权威Authoritative响应集合addlset[string]logoptional当前查询的附加Additional响应集合由于两个字段都带log它们会作为独立列出现在 dns.log 中因为类型是set[string]同一查询的多个权威/附加响应会被累积成一个集合从源码结构看Zeek 日志中将以逗号分隔的字符串形式输出集合内容。optional表示该字段可能不存在例如查询未带权威/附加区段时。2.3 处理每个响应的 hookDNS::do_replyhook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) priority5 { if ( msg$opcode ! 0 ) # Currently only standard queries are tracked. return; if ( ! msg$QR ) # This is weird: the inquirer must also be providing answers in # the request, which is not what we want to track. return; if ( ans$answer_type DNS_AUTH ) { if ( ! c$dns?$auth ) c$dns$auth set(); add c$dns$auth[reply]; } else if ( ans$answer_type DNS_ADDL ) { if ( ! c$dns?$addl ) c$dns$addl set(); add c$dns$addl[reply]; } }这段 hook 的逻辑要点只跟踪标准查询msg$opcode ! 0直接返回。意味着动态更新UPDATE、NOTIFY 等 opcode 的报文不会进入本脚本的处理范围这与基座dns_message事件对 opcode 的过滤思路一致参见 main.zeek。只处理响应方向msg$QR必须为真QR 标志表示这是 DNS 响应而非查询。注释点明了一个边缘场景如果请求方在查询报文中也携带了答案这种异常情形不被跟踪。按answer_type分类收录当解析器为某个记录调用本 hook 时根据ans$answer_type是DNS_AUTH还是DNS_ADDL把格式化后的reply字符串加入c$dns$auth或c$dns$addl集合首次写入前先初始化空集合。DNS_AUTH与DNS_ADDL是基座脚本定义的常量init-bare.zeekconst DNS_QUERY 0; ## A query. This shouldnt occur, just for completeness. const DNS_ANS 1; ## An answer record. const DNS_AUTH 2; ## An authoritative record. const DNS_ADDL 3; ## An additional record. const DNS_PREREQUISITE 4; ## A prerequisite record for dynamic update. const DNS_UPDATE 5; ## A update record for dynamic update.dns_answer记录类型也定义在 init-bare.zeek包含answer_type、query、qtype、qclass、TTL等字段hook 正是通过answer_type区分记录归属。2.4 与基座 hook 的分工值得注意的是DNS::do_reply是一个 hook可注册多个 handler按priority排序执行base/protocols/dns/main.zeek 中也注册了同名 hook同样priority5但它只处理DNS_ANS、DNS_PREREQUISITE、DNS_UPDATE三种类型用于填充c$dns$query等基础字段if ( ans$answer_type ! DNS_ANS ans$answer_type ! DNS_PREREQUISITE ans$answer_type ! DNS_UPDATE ) return;而 auth-addl.zeek 中的 hook 恰好补上了DNS_AUTH与DNS_ADDL两类。两者互不冲突、职责互补共同构成对 DNS 响应的完整覆盖。三、底层 C 实现跳过逻辑与解析流程该脚本能生效的前提是 C 层确实放了行。在 src/analyzer/protocol/dns/DNS.cc 中可以看到完整判定逻辑bool skip_auth (zeek::detail::dns_skip_all_auth ! 0); bool skip_addl (zeek::detail::dns_skip_all_addl ! 0); if ( msg.an_pr_count 0 ) { // We did an answer, so can potentially skip auth/addl. static auto dns_skip_auth id::find_valTableVal(dns_skip_auth); static auto dns_skip_addl id::find_valTableVal(dns_skip_addl); auto server make_intrusiveAddrVal(analyzer-Conn()-RespAddr()); skip_auth skip_auth || msg.ns_up_count 0 || dns_skip_auth-FindOrDefault(server); skip_addl skip_addl || msg.arcount 0 || dns_skip_addl-FindOrDefault(server); } if ( skip_auth skip_addl ) { // No point doing further work parsing the message. EndMessage(msg); return; }这段代码揭示了完整的跳过决策树全局开关dns_skip_all_auth/dns_skip_all_addl即脚本通过redef置为F的两个变量是总闸即使全局开关为假若报文本身没有该区段权威记录数ns_up_count 0、附加记录数arcount 0也会跳过若对端服务器地址命中集合dns_skip_auth/dns_skip_addl按 IP 精确跳过同样跳过只有当权威与附加都需解析时才继续解析 Authority 区段DNS_AUTHORITY动态更新报文无此区段与 Additional 区段并为每条记录触发事件、调用脚本层 hook。这两个按 IP 的跳过集合同样定义在 init-bare.zeek可以在策略脚本之外单独使用## For DNS servers in these sets, omit processing the AUTH records they include ## in their replies. global dns_skip_auth: set[addr] redef; ## For DNS servers in these sets, omit processing the ADDL records they include ## in their replies. global dns_skip_addl: set[addr] redef;在 src/NetVar.cc 与 src/NetVar.cc 中这些变量被声明为全局数据并在初始化时通过id::find_val(...)-AsBool()从脚本层读取布尔值——这也解释了为什么脚本层redef的改动能在解析时立即生效。四、使用方式与测试验证4.1 加载方式在 Zeek 中加载该策略脚本有两种等价方式# 方式一在 local.zeek 或脚本中按策略包路径加载 load policy/protocols/dns/auth-addl # 方式二命令行直接指定 zeek -r capture.pcap policy/protocols/dns/auth-addl加载后dns.log 中每行查询记录将额外携带auth与addl两列当对应区段存在时。需要注意的是由于auth/addl字段声明为optional无权威/附加记录的查询不会输出空列。4.2 测试用例inverse-request仓库自带回归测试 testing/btest/scripts/policy/protocols/dns/inverse-request.zeek# TEST-EXEC: zeek -b -r $TRACES/dns-inverse-query.pcap %INPUT # TEST-EXEC: test ! -e dns.log load protocols/dns/auth-addl该测试针对反向查询inverse query流量由于这种报文的 opcode 不是标准查询msg$opcode ! 0hook 直接返回因此期望不产生 dns.log。这恰好从测试角度印证了脚本仅跟踪标准查询的行为边界。4.3 与事件处理相关的连锁影响开启dns_skip_all_addl F还会让一系列依赖附加区段的事件恢复触发。反之当该开关保持默认的T时scripts/base/protocols/dns/check-event-handlers.zeek 会在zeek_init时发出警告提醒用户某些事件将不再触发if ( ! dns_skip_all_addl ) return; local addl_functions [dns_TSIG_addl, dns_EDNS_addl, dns_EDNS_ecs, dns_EDNS_tcp_keepalive, dns_EDNS_cookie]; for ( event_name in addl_functions ) if ( is_event_handled(event_name) ) Reporter::warning(fmt(Used event %s will not be raised because dns_skip_all_addl is true, event_name)); if ( is_event_handled(dns_TKEY) ) Reporter::warning(Used event dns_TKEY will not contain any data in ans because dns_skip_all_addl is true);这些附加区段相关事件如 EDNS、TSIG、TKEY、DNS Cookie 等在 src/analyzer/protocol/dns/events.bif 中也有对应文档注释明确标注仅当dns_skip_all_addl为假时才会触发。因此加载 auth-addl 脚本不仅能得到更完整的日志也解锁了这些事件的产生。4.4 性能权衡与推荐场景回到原文档的核心警告本脚本不推荐用于重负载链路not recommended for use on heavily loaded links。原因在于权威与附加记录的数量通常远多于 Answer 记录例如大 DNS 响应中的 NS 记录、SOA 记录、额外的 A/AAAA glue records、EDNS 信息等每条记录都需要走完解析 → 事件生成 → hook 处理的完整链路见上文 DNS.cc 的解析路径开销随记录数线性放大。因此合理的使用姿势是在中等流量、安全取证/威胁狩猎场景下开启换取完整的 DNS 上下文可见 NS/SOA/glue 等权威信息有助于识别 DNS 劫持、域前置、恶意权威域等行为在高吞吐生产链路上优先保持默认跳过或用dns_skip_auth/dns_skip_addl按特定 DNS 服务器 IP 做定点豁免而不是全局开启结合dns_max_queriesinit-bare.zeek默认 25等保护性参数使用避免畸形流量放大开销。五、总结policy/protocols/dns/auth-addl.zeek是 Zeek DNS 分析能力的一个精准补充它通过redef打开基座默认关闭的权威/附加区段解析开关以DNS::do_replyhook 收集记录并扩展DNS::Info的auth、addl两个log字段最终让 dns.log 携带更完整的 DNS 语义。其背后的控制开关dns_skip_all_auth/dns_skip_all_addl/dns_skip_auth/dns_skip_addl在 init-bare.zeek 中定义、在 DNS.cc 中执行形成了一条从脚本配置到 C 解析的完整链路。使用它的关键判断在于用可观的 CPU 开销换取权威与附加响应的可见性——这条取舍文档与源码都已给出了明确的答案。赞分享网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载相关推荐Zeek dns.log 深度解析DNS 日志字段、查询流程与实战分析方法Zeek dns.log 深度解析DNS 日志字段、查询流程与实战分析方法 导读 dns.log 是 Zeek 生成的最重要数据源之一它记录了网络内每一笔应网络安全网络IDSZeek DNS 协议分析脚本base/protocols/dns/main.zeek深度解析日志字段、查询/响应关联与源码实现Zeek DNS 协议分析脚本base/protocols/dns/main.zeek深度解析日志字段、查询/响应关联与源码实现 导读 scripts/b网络安全网络IDSZeek 策略脚本深度解析使用 vlan-logging 将外层/内层 VLAN 信息写入连接日志Zeek 策略脚本深度解析使用 vlan logging 将外层/内层 VLAN 信息写入连接日志 导读 vlan logging 是 Zeek 提供的一个轻网络安全网络IDS上一篇Nuclei Templates终极指南5分钟快速上手安全扫描下一篇如何快速掌握Binary Ninja二进制分析的Python原型工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑