01 · 投毒技术演进:从16位到纵深
1.1 经典生日攻击
DNS应答的有效性曾几乎只依赖一个16位事务ID。攻击者在真实应答到达前批量注入伪造应答,只要碰撞成功,伪造记录即写入缓存。按生日悖论,理想化模型下数千次尝试即可在典型竞态窗口内命中——而UDP无握手特性让"在窗口内多发"几乎没有成本。
1.2 Kaminsky攻击(2008):把概率问题变成时间问题
Dan Kaminsky的关键洞察是绕过"每域名缓存锁定":当查询example.com的A记录时,攻击者不必硬猜该记录的应答,而是猜测附加段中example.com的权威NS记录——伪造NS指向攻击者控制的域名服务器。即便投毒失败,否定应答也会迅速过期(否定缓存远短于权威TTL),下一轮尝试马上可以开始;且攻击者可同时对多个不同域名并行下注。这本质上是把"单次竞态"重构为"每秒多次、长期持续"的资源竞赛,使16位熵在小时级时间内形同虚设。CERT以VU#800113协调全球厂商于2008年7月同步发布补丁,采用源端口随机化:将16位事务ID与16位源UDP端口组合为约32位熵,把成功概率稀释约6万倍量级。
1.3 后补丁时代的残余风险
- 熵源质量:32位组合熵的前提是端口真随机。研究显示部分实现的端口分配存在可预测性(如顺序分配、哈希聚集),审计须实测源端口分布的均匀性;
- 分片绕过:IP分片重组路径可能绕过部分实现的端口校验假设,RFC 8906及后续研究持续讨论该面;
- 0x20编码的兼容边界:大小写混合编码(RFC 5452)为查询名增加数十比特熵,但要求权威正确回显大小写,个别老旧权威不兼容会被回退关闭;
- 实现缺陷:如Unbound幽灵域名漏洞(CVE-2020-12663,2020年6月修复)使恶意权威可通过操纵缓存时间线让已下线域名"复活",属于协议之外的实现层污染路径。
02 · 防御纵深矩阵
| 防御层 | 机理 | 覆盖盲区 | 审计验证 |
|---|---|---|---|
| 源端口随机化 | 事务ID×源端口组合约32位熵(CVE-2008-1447的标准修复) | 端口分配缺陷、IP分片、中间NAT改写 | 抓包统计源端口分布均匀性 |
| 0x20编码 | 查询名随机大小写,权威须原样回显(RFC 5452) | 权威不兼容回退;子域规则例外 | dig以大小写混合查询,核对回显 |
| DNS Cookie | OPT记录中的事务凭证(RFC 7873),弱密钥下亦可显著提升伪造成本,并能抵御盲注 | 权威不支持时降级;Cookie非加密凭证 | 检查响应中是否回显有效Cookie |
| DNSSEC验证 | RSA/ECDSA签名链验证(RFC 4033-4035),伪造应答无法通过密码学校验 | 未签名区域无保护;验证关闭/CD滥用;算法降级 | delv验证+AD位核查+bogus计数监测 |
| QNAME最小化 | 迭代查询逐步暴露最小查询名(RFC 7816),收窄窃听与操纵面 | 少数权威不兼容导致的回退 | 上游抓包验证逐级暴露模式 |
| Aggressive NSEC | 用缓存的NSEC/NSEC3证明直接应答不存在(RFC 8198),减少实时迭代暴露面 | NSEC3参数强度依赖区配置 | 配置核查+NXDOMAIN路径测试 |
组合策略:四层机制解决的是不同问题——端口/0x20/Cookie抬高伪造的熵与成本,DNSSEC在数学上终结未授权篡改,QNAME最小化与aggressive NSEC收窄暴露面。审计达标线应为:熵类机制全开且经验证有效、DNSSEC验证开启且bogus可观测、隐私增强机制默认开启。任何"开了但无证据"的配置在审计口径中视为未开启。
2.1 DNSSEC验证的落地要点
- 信任锚维护:根区KSK自2010年7月15日首次签署以来已历经首次KSK轮转(2018年10月,HSM根KSK由ICANN/Verisign依RFC 5011流程推进)——递归器必须支持自动信任锚更新,审计时检查信任锚文件的获取与更新通道;
- 验证失败处置:对bogus应答返回SERVFAIL是正确纪律(防降级剥离);Unbound的harden-dnssec-stripped专门封堵"剥离签名导致验证不可行"的降级路径;BIND的dnssec-validation auto为推荐基线;
- CD位滥用:对来自非管理源的CD=1查询应结合策略评估,防止攻击者借CD位绕过验证后命中缓存(缓存应按"是否经验证"分层管理,此为实现细节,审计以厂商文档为准)。
03 · bailiwick与信任边界
bailiwick规则规定递归器只能缓存"与查询名同域或其子域"的记录,其目的在于:即使攻击者控制了example.com的权威,也不能借应答中的附加段把bank.com的NS记录塞进你的缓存。Kaminsky攻击正是钻了当年部分实现附加段校验宽松的漏洞。现代基线:
- BIND:fetch-glue no(禁止为附加段记录做额外递归获取)、minimal-responses yes(精简附加段,同时缩小放大体积——与第3页抗DDoS目标协同);
- Unbound:harden-referral-path系列选项收紧委托链校验;
- 嵌入式转发器:dnsmasq类实现历史上对委托链校验的实现深度弱于主流递归器,且固件更新滞后——这是家用与企业访客网络中最常被忽视的bailiwick盲区,审计时以"版本+上游边界"双重确认。
幽灵域(Ghost Domain)警示:CVE-2020-12663(Unbound,2020年修复)揭示了协议之外的污染路径:恶意权威通过精确操纵应答时间线,使本应过期的委托信息在缓存中"续命",让已下线的恶意域名持续可解析。它提醒我们:缓存完整性审计必须覆盖时间语义(TTL起算、过期处理、预取行为),而不仅是记录内容。
04 · NXDOMAIN与否定缓存攻击面
4.1 水刑攻击的缓存侧伤害
随机子域("水刑")攻击除带宽消耗外,还会对缓存造成结构性伤害:海量随机子域名触发权威返回NXDOMAIN,按RFC 2308这些否定结果被缓存,缓存空间被低价值否定记录挤占,正常记录命中率下降、被迫增加上游迭代——可用性与完整性双重受损。第3页的NXDOMAIN类响应RRL是第一道闸;缓存侧的第二道闸是上限控制与分区(部分实现支持对否定缓存设独立配额)。
4.2 否定缓存操纵
攻击者控制(或攻陷)某区域权威时,可通过极短的SOA MINIMUM TTL缩短否定缓存驻留,或借NSEC/NSEC3证明结构探测区域内容。防御侧:aggressive NSEC(RFC 8198)用已有签名证明直接应答,减少与恶意权威的实时交互;审计侧:监测否定缓存占比与SOA TTL异常分布。
05 · 缓存窥探(Snooping)与隐私
缓存窥探的原理:攻击者探测某域名在缓存中的剩余TTL——若明显小于权威原始TTL,说明近期有用户访问过该域名。借此可对解析器用户群做兴趣画像(访问了哪些医疗、金融、内部系统域名),属于常被忽略的侧信道泄露。
| 缓解措施 | 说明 | 适用性 |
|---|---|---|
| 统一过期时间 | 缓存记录按"整批过期"管理,剩余TTL不再反映真实访问时间(部分实现支持此类缓存调度) | 公共递归/多用户场景 |
| 拒绝间接探测 | 对"查询他人已缓存域名"的请求与普通请求返回不可区分(一致性应答) | 取决于实现,核查厂商文档 |
| 缓存分区 | 按用户组/网段隔离缓存,缩小单一缓存的画像面 | 企业多租户场景 |
| 查询审计与告警 | 对典型探测模式(低频、广泛覆盖、TTL采样型查询序列)建立检测规则 | 通用 |
说明:缓存窥探的缓解能力因实现而异,审计时应以实测验证为准,不以"理论上可配置"代替验证证据。
06 · 验证方法与检查清单
6.1 关键验证命令(授权环境内执行)
- 熵源分布实测:连续发起多条递归查询并抓包,统计源端口与事务ID的分布均匀性——这是"端口随机化是否名实相符"的唯一硬证据;
- 0x20回显验证:以大小写混合名称查询并比对应答回显;
- Cookie协商:检查EDNS Cookie的往返有效性(RFC 7873交互流程);
- DNSSEC验证链:用delv(BIND工具链)对签名/未签名域名分别验证,确认bogus域名返回SERVFAIL且日志计数增长;
- AD位证据链:确认对管理域的应答在DO查询下带AD位,证明验证真实发生;
- QNAME最小化验证:执行
dig txt qnamemintest.internet.nl(internet.nl/SIDN 提供的公开测试域),根据应答内容判定最小化是否生效。
6.2 D2域检查清单
| 项 | 检查项 | 方法 | 合格判据 |
|---|---|---|---|
| 1 | 源端口随机化实测分布均匀 | 抓包统计 | 均匀、无聚集 |
| 2 | 0x20编码开启且未因兼容性静默回退 | 混合大小写实测 | 回显一致 |
| 3 | DNS Cookie协商有效 | EDNS选项观测 | 有效回显 |
| 4 | DNSSEC验证开启(dnssec-validation auto / harden-dnssec-stripped) | 配置+delv | 验证生效 |
| 5 | bogus应答处置为SERVFAIL且无静默降级 | 测试域验证 | SERVFAIL+日志 |
| 6 | 信任锚自动更新机制有效 | RFC 5011流程核查 | 通道可用 |
| 7 | bailiwick收紧(fetch-glue no / harden-referral-path)与minimal-responses | 配置审计 | 已启用 |
| 8 | QNAME最小化开启(RFC 7816) | 上游抓包 | 逐级暴露 |
| 9 | 否定缓存占比与NXDOMAIN限流联动监测 | 遥测 | 基线在跑 |
| 10 | 缓存窥探缓解实测(TTL采样探测不可区分) | 授权内探测 | 不可区分 |
小结:D2域的达标姿态是——伪造进不来(熵+验证)、进来了看得见(bogus可观测)、看不穿用户(抗窥探)。下一页转向"让软件本身不成为短板"的实现与配置基线审计。
本节参考来源(第4页)
投毒机理与防御机制的权威出处如下。
US-CERT VU#800113(Kaminsky漏洞协调公告,2008年7月):kb.cert.org/vuls/id/800113;CVE-2008-1447:cve.org
RFC 5452(抗伪造措施与0x20)、RFC 7873(DNS Cookie)、RFC 7816(QNAME最小化)、RFC 8198(aggressive NSEC)、RFC 2308(否定缓存)、RFC 4033/4034/4035(DNSSEC)、RFC 5155(NSEC3):rfc-editor.org
ICANN根区KSK轮转(2018年10月11日)公开资料:icann.org/kskroll;RFC 5011(自动信任锚更新)
CVE-2020-12663(Unbound幽灵域名)及NLnet Labs安全公告:nlnetlabs.nl
BIND ARM(fetch-glue、minimal-responses、dnssec-validation):bind9.readthedocs.io;Unbound文档(harden-*):unbound.docs.nlnetlabs.nl