本文只处理你有权分析的日志;示例中的 IP、域名和时间都是合成值。分诊的目标是提出可验证的问题,不是封禁客户端、扫描域名或声称“发现了隧道”。实际响应仍需遵循组织的值班、隐私和留存规则。
边界与问题定义
先写清楚观察窗口、传感器位置、递归解析器和时区。一个问题应能被证据回答,例如“在 00:00—00:10,哪台已授权的端点向哪个解析器发出了异常多的失败查询?”而不是“这个域名是不是恶意”。没有边界,阈值会把 CDN、软件更新和用户行为混成一团。
先读懂字段
Zeek 的 dns.log 记录 DNS 活动;不同版本和脚本可能增删字段,所以先看文件里的 #fields 与 #types。常用字段的分工如下:
| 字段 | 分诊用途 | 不要过度解读 |
|---|---|---|
ts、uid | 还原时间顺序;用 UID 关联 conn.log。 | UID 只标识这次连接,不代表文件或进程。 |
id.orig_h/p | 定位发起端和临时端口,结合 DHCP、资产或端点日志。 | NAT、转发器会让“来源 IP”不等于最终用户。 |
id.resp_h/p、proto | 确认查询到哪台解析器、走 UDP 还是 TCP。 | 看到 53 端口不等于看到了端点所有 DNS。 |
query、qtype、rcode | 观察名称、记录类型和 NOERROR/NXDOMAIN 等结果。 | 一个 NXDOMAIN 可能只是拼写错误或服务发现重试。 |
answers、TTLs、TC/rejected | 比较返回内容、缓存时间、截断和解析异常。 | 缺失答案可能来自采集丢包或字段未启用。 |
官方示例还展示了同一 uid 下 AAAA 与 A 两条 DNS 交换;这说明“重复域名”可能只是正常的双栈解析。遇到可疑行,先沿 UID 回到 conn.log,再与端点进程、代理和身份时间线对齐。
覆盖面与 DoH 盲区
传感器只有在能看到 DNS 会话的位置才会产生日志。部署在出口的 Zeek 可能看到端点到企业递归器的请求,却看不到递归器向权威服务器发出的后续请求;部署在服务器网段则可能漏掉办公网和漫游设备。镜像端口、采集过滤器、丢包和时钟偏差都应写进分诊记录。
DoT(DNS over TLS)和 DoH(DNS over HTTPS)把查询封装进加密连接,传统 DNS 分析器无法读取 query。DoH 还可能与普通 HTTPS 共用端口和基础设施,因此“dns.log 没有记录”不是“没有 DNS”。在授权环境中,可用端点解析器日志、企业代理的合规元数据、浏览器策略或加密流量的目的地信息补齐视角;不要为了绕过加密去解密他人内容。
离线分诊步骤
- 保存原样。复制原始
dns.log,记录哈希、采集时间、传感器和脱敏方式;分析副本,避免改写证据。 - 先跑透明规则。
dnswatch是离线只读工具,不解析域名、不发包。它按长度、熵、频次、NXDOMAIN 比例和少量 TLD 线索输出 table、JSON 或 SARIF。 - 回看上下文。把命中行按客户端、时间窗、解析器和 UID 聚合,再查资产基线、进程、代理和变更记录。每个结论标注“观察到的事实”或“待验证的推断”。
- 提出下一步。只在授权范围内做最小复验,例如重放本地合成日志、确认解析器配置,或请端点团队提供同一时间窗的进程证据。
# 在 E:\moban2 环境中从仓库根目录运行;不会访问网络
python -m dnswatch.cli secx-security-blog/samples/network/zeek-dns-synthetic.log --format table --max-query-length 30
python -m dnswatch.cli secx-security-blog/samples/network/zeek-dns-synthetic.log --format json
合成样本故意让一个客户端产生多条 NXDOMAIN 和较长标签。它用于观察输出,不代表恶意流量。
弱信号如何组合
长度可以提示编码或生成内容,但追踪参数、软件更新和服务发现也会很长。熵高只说明字符分布更均匀,随机 ID、压缩标识和哈希同样会触发。频次需要窗口和基线,否则健康检查也像 beacon。NXDOMAIN 比例尤其容易受拼写错误、搜索后缀和停用服务影响:熵、NXDOMAIN、长度都只是弱信号,单独不能证明隧道;即便三者同时出现,也要结合进程和流量方向复验。
一个可解释的排序方式是:同一客户端、同一时间窗内,先按异常查询数排序,再查看长标签是否持续变化、失败比例是否显著高于该客户端基线、是否存在对应的进程或变更。不要把阈值写成“命中即隔离”;把规则 ID、阈值、原始行和复验结果一起留档,下一次调参才有依据。
误报、限制与复验清单
- 是否确认采集点能看到目标端点、UDP/TCP DNS 和时间窗口?是否查过
capture_loss.log或传感器告警? - 是否把客户端 NAT、递归器缓存、AAAA/A 双查询、CDN 和软件更新列入基线?
- 是否检查 DoH/DoT、应用内解析、VPN 或外部递归器导致的可见性缺口?
- 每条发现是否保留原始行号、UID、客户端、解析器、规则参数和分析者判断?
- 是否只使用合成或已授权数据,并在分享前移除用户标识、完整域名和令牌?
把 DNS 规则当作“下一次查什么”的提示器,调查才不会被一个漂亮的分数牵着走。
资料与来源
- Zeek 官方:dns.log 字段与示例(字段语义、UID 关联和解析记录)。
- Zeek 官方:日志格式与离线检查(TSV 头部、
#fields与离线处理)。 - Zeek 官方:DNS 协议分析器(UDP/TCP 分析范围与事件)。
- IETF RFC 8484:DNS over HTTPS(加密 DNS 的协议边界)。