手工构造DNS根NS查询请求在1.1.1.1失败但在8.8.8.8成功的原因排查
手工构造DNS根NS查询请求在1.1.1.1失败但在8.8.8.8成功的原因排查
你遇到的这个问题核心原因在于Cloudflare的1.1.1.1对无EDNS扩展的基础DNS请求有特殊处理逻辑,而Google的8.8.8.8则兼容这类传统的无扩展请求。
先拆解下你构造的请求包:
- 事务ID:
0x28c2 - 标志位:
0x0100(标准递归查询) - 问题数:1,后续的回答数、权威数、额外数都是0
- 查询内容:根域(空标签)的NS记录(类型
0x0002,IN类0x0001)
这个包的结构本身是符合基础DNS协议规范的,但你也注意到了——dig工具发送的请求多了一条EDNS0扩展记录。这就是关键差异点:
EDNS0是DNS协议的扩展标准,主要用来解决传统DNS UDP包大小限制、支持更多功能选项的问题。现在很多现代公共DNS服务(包括Cloudflare 1.1.1.1)会优先要求请求携带EDNS扩展,甚至对不带EDNS的请求直接返回空响应(或者不返回完整结果)。而Google的8.8.8.8对这类老的无EDNS请求兼容性更好,所以能正常返回13条根NS记录。
解决办法
你需要在手工构造的DNS包末尾添加EDNS0扩展记录,基本结构如下:
- 伪域名:空标签(
\x00) - 类型:OPT(
0x29,对应十进制41) - 类:UDP payload大小(比如设为
0x1000,即4096字节) - TTL:包含EDNS版本(通常是0)和标志位(可以设为0)
- RDATA长度:0(如果不需要额外选项)
举个例子,你可以在原请求字节流b'(\xc2\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01'的末尾追加\x00\x00\x29\x00\x10\x00\x00\x00\x00\x00,构造出带EDNS0的请求包,再发送给1.1.1.1就能拿到正常的根NS记录了。
备注:内容来源于stack exchange,提问作者Elia
相关产品推荐
相关产品推荐

