摘要
DNS 泄露是一个被广泛讨论、却经常被讲错的话题。很多材料把它描述为"DNS 请求暴露了你的真实 IP",这在技术并不严谨------在标准解析链路中,权威服务器看到的是递归解析器的地址,而不是终端设备的地址。真正的 DNS 泄露,指的是你的解析请求没有走你预期的解析器,导致解析路径与访问路径分属不同的网络归属。本文从解析链路的角色划分讲起,说明三种典型的泄露形态,介绍用一次性随机权威域名建立对照基线的方法,给出命令行与服务端的复现手段,并讨论加密 DNS(DoH/DoT)、EDNS Client Subnet 对检测结论的影响,最后总结判断口径与加固建议。
一、先把解析链路的角色分清楚
1.1 一次递归解析的四段旅程
当你在浏览器里输入一个域名,标准解析流程大致经过以下环节:
- 存根解析器(stub resolver):操作系统或浏览器内部的解析组件,负责把查询发给配置好的递归解析器。
- 递归解析器(recursive resolver):通常由 ISP、公共 DNS 服务或企业内网提供。它负责从根开始逐级询问,并把结果缓存下来。
- 根与顶级域(TLD)服务器 :递归解析器向它们询问"
.com的权威服务器是谁"。 - 权威服务器(authoritative server):域名持有者自己部署或托管,最终给出 A/AAAA/CNAME 等记录。
关键在于第 4 步:权威服务器的日志里,源地址是第 2 步那个递归解析器的地址。对绝大多数配置而言,终端设备的地址根本不会出现在权威日志中。
1.2 那么"DNS 泄露"到底指什么
理解了上面的链路,才能给出准确的定义。DNS 泄露指的是:你在访问某个业务时,解析该域名的递归解析器不是你预期的那一个,从而把解析行为暴露给了另一个网络归属方。
最常见的例子是:浏览器配置了代理,HTTP 流量确实从代理节点出去了,但域名解析仍然由本地运营商提供的 DNS 完成(因为系统网络接口上的 DNS 没有被改动)。结果是------
- 访问路径:代理节点所在地区;
- 解析路径:本地运营商,甚至本地城市。
两者不一致,就构成了泄露。它带来的实际后果不是"你的 IP 被公布在公网",而是解析行为与访问意图出现矛盾,这在多账号运营、地域限制类业务、企业合规审计中都可能成为异常信号。
1.3 三种典型形态
| 形态 | 表现 | 常见成因 |
|---|---|---|
| 解析器未跟随代理 | HTTP 出口为代理,解析器仍为本地运营商 | 只改了 HTTP 代理,未改 DNS 配置或未启用代理的 DNS 转发 |
| 部分域名走本地 | 部分域名由本地解析,部分由代理侧解析 | PAC 规则、分流策略、域名白名单不完整 |
| 加密 DNS 造成盲区 | 检测侧完全观测不到解析请求 | 浏览器启用了 DoH,绕过了系统 DNS 与本地缓存 |
第三种形态容易被忽视:启用 DoH 之后,检测工具往往什么也看不到,于是被误判为"安全"。这一点在后文会单独讨论。
二、检测原理:用一次性权威域名建立基线
2.1 为什么要用从未被查询过的随机域名
检测的核心难点在于可观测性。你不能去读别人的权威服务器日志,所以必须准备一个自己可控的观测点。
工程上的做法是:生成一个一次性的、随机的子域名 ,例如 6e91f6461f9a50b95ec69e83.leak.example.com,让前端页面去解析它,同时在权威侧记录所有到达的查询来源。为了让观测窗口可控,这个子域名通常会在很短时间内失效(例如 2 分钟后不再响应有效记录)。
随机性在这里有三个不可替代的作用:
- 排除缓存干扰:这个名字从未被任何人查询过,不可能命中递归解析器上的缓存,因此每一次解析都必然真实地走到权威侧;
- 排除预取干扰:常见的预解析、预连接优化无法提前命中一个随机名字;
- 建立唯一关联:每次检测生成独立的域名,可以把某一次观测精确地对应到某一次操作。
2.2 权威服务器这一侧能记录什么
当查询到达权威服务器时,可记录的字段包括:
- 递归解析器的源地址(IPv4 / IPv6);
- 该地址的 BGP 宣告前缀与 Origin ASN;
- ASN 的注册国家与运营商元数据;
- 该地址的地理库推断位置(城市级,非精确)。
把这些字段组合起来,就能回答一个具体问题:这次解析是从哪个网络、哪个运营方发起的。 这正是判断"解析路径是否与访问路径一致"所需的全部信息。
2.3 建立对照基线:与 HTTP 出口比较
单看解析器地址仍然没有意义,必须有一个参照。最自然的参照就是当前页面的 HTTP 出口------浏览器访问检测站点时,服务端在应用层看到的源地址及其归属。
于是判断逻辑与 WebRTC 检测的思路一致:
- 解析器归属 ≈ HTTP 出口归属(同一 ASN、同一运营商)→ 未发现不一致;
- 解析器归属 ≠ HTTP 出口归属 → 需要进一步确认是不是分流或本地 DNS;
- 解析器归属为本地运营商,HTTP 出口为境外代理 → 典型的解析路径未跟随代理。
这里有一个重要的技术提醒:比较的是"归属",不是"地址相等"。 递归解析器的地址和终端的出口地址从来不会是同一个 IP(除非你自建解析器)。判断依据是 ASN、运营商类型和线路属性,而不是字符串相等。
2.4 为什么"未观测到"不能当作"没有泄露"
这是全文最需要强调的一点。检测侧显示"未观测到 DNS 查询",至少有以下几种可能:
- 浏览器启用了 DoH,查询走了 HTTPS 通道,不经过系统 DNS;
- 本地或上游递归解析器存在缓存,查询没有到达权威;
- 网络策略拦截了对外部权威的查询;
- 检测窗口太短,查询发生在窗口之外;
- 解析请求被设备上的安全软件接管。
这些情况的共同点是:我们只是没有观测到,并不代表解析行为不存在或不异常。 因此一个严谨的检测结论应当写成"本次未观测到",而不是"无泄露"。这两句话在排障语义上差别巨大,前者提示需要换一种观测手段,后者会让人直接停止排查。
2.5 与 DNS 污染、解析劫持的区别
这三个概念经常被混在一起,但成因与排查手段完全不同,值得明确分开:
| 问题 | 现象 | 根因位置 | 排查入口 |
|---|---|---|---|
| DNS 泄露 | 解析走了非预期的解析器 | 终端与代理配置 | 解析器归属与 HTTP 出口对比 |
| DNS 污染 | 返回了明显错误的记录 | 链路中间设备 | 多地区查询结果对比 |
| 解析劫持 | 返回广告页或跳转地址 | 运营商或本地设备 | 权威记录与实测记录对比 |
泄露关注的是"谁在解析",污染关注的是"解析结果对不对",劫持关注的是"结果被谁改了"。一次完整的排查应当三个方向都覆盖:先看解析器归属,再看多地结果是否一致,最后与权威记录核对。
2.6 检测窗口的设计
观测窗口太短,会出现大量假阴性;窗口太长,又会把后续无关的解析行为混进来。工程上通常遵循两条经验:
- 窗口覆盖完整的页面加载周期,因为现代页面在首屏之后还会触发多轮解析;
- 在窗口结束后给出明确的截止状态,例如"本次检测窗口内无结果",而不是一直显示"检测中"。
把窗口状态明确暴露给使用者,是检测工具设计上容易被忽略、但直接影响结论可信度的一环。
三、DNS 出口的三类判据
3.1 解析器来源地址与协议
首先要记录的是源地址本身,并区分 IPv4 与 IPv6。双栈网络中,解析器的 IPv4 与 IPv6 地址可能归属不同运营方,这在企业网络里尤其常见------例如 IPv4 走内网递归,IPv6 走运营商递归。
3.2 Origin ASN 与运营商属性
仅有地址不足以判断归属,还需要把它映射到 BGP 前缀与 Origin ASN。实践中要留意几类容易误判的情况:
- Anycast 公共 DNS:同一地址在全球多点宣告,位置推断可能落在任意节点,不能据此判断真实位置;
- 运营商递归集群:同一运营商在不同省份有不同出口,地址变化不代表配置变化;
- 云上自建解析器:归属显示为云服务商,需要结合业务部署位置理解。
3.3 地理位置的正确用法
地理位置来自商业地理库,属于推测值。它的合理用法是"辅助判断",例如"解析器落在与 HTTP 出口完全不同的国家"。把城市级推断当作精确定位来使用,几乎一定会得出错误结论------机房、注册地和实际使用地三者在现实中经常不同。
3.4 递归解析器与转发器的差别
还有一个技术细节会影响结论解读:你在网络配置里填的那个 DNS 地址,未必就是真正执行递归的一方。
- 纯递归解析器:自己从根开始逐级查询,权威侧看到的源地址就是它。
- 转发器(forwarder) :把请求转给上游解析器,自己只做缓存。此时权威侧看到的源地址是上游的地址,而不是你配置的那个。
家庭路由器、部分企业 DNS 和云厂商的解析服务都可能采用转发模式。于是在检测结果里,解析器地址与你在配置里写的地址不一致,是完全正常的,需要结合转发链路上游来判断归属,而不是直接判定为异常。
四、动手复现:命令行侧的验证方法
在线检测之外,命令行是更可控的验证手段,也是排查时的第一手资料。
bash
# 1. 查看本机当前使用的解析器
scutil --dns | grep nameserver # macOS
cat /etc/resolv.conf # Linux(注意 systemd-resolved 场景)
# 2. 直接查询权威服务器,绕过本地递归
dig +norecurse @ns1.example.com www.example.com A
# 3. 指定解析器查询,用于对比不同解析器的结果
dig @223.5.5.5 www.example.com A +short
dig @8.8.8.8 www.example.com A +short
# 4. 完整追踪解析路径,观察经过哪些环节
dig +trace www.example.com
# 5. 检查是否携带 EDNS Client Subnet(会把客户端子网传递出去)
dig @8.8.8.8 www.example.com +subnet=0.0.0.0/0
4.1 关于 EDNS Client Subnet 的补充
上一条命令涉及一个容易被忽略的机制:EDNS Client Subnet(ECS)。开启 ECS 后,递归解析器会把客户端的部分子网信息附带在查询中,让权威侧或 CDN 能做就近调度。
这对检测有直接影响:如果开启了 ECS,你的部分网络位置信息会通过 DNS 传递出去,即便解析器本身不是你本地的。也就是说,解析器归属一致并不必然意味着没有任何信息外泄。是否开启 ECS 属于策略取舍:它对就近调度有帮助,同时也会传递客户端网段。
4.2 结果对照的最小矩阵
把命令行结果整理成矩阵,一眼就能看出不一致:
| 观测项 | 期望值 | 实测值 | 判定 |
|---|---|---|---|
| HTTP IPv4 出口 | 代理节点 A 段 | A 段 | 符合 |
| 系统解析器 | 代理侧 DNS | 本地运营商 DNS | 不一致 |
| 解析器 Origin ASN | 与 A 段同 ASN | 本地 ISP ASN | 不一致 |
| 查询是否携带 ECS | 关闭 | 开启 | 需评估 |
五、常见网络架构下的典型表现
不同架构下,DNS 出口的表现差异很大。下面这张表可以作为快速定位的参照:
| 架构 | 解析器位置 | 检测常见结果 |
|---|---|---|
| 仅浏览器 HTTP 代理 | 系统 DNS | 解析器为本地运营商,与代理出口不符 |
| 全局 VPN(含 DNS) | VPN 侧 DNS | 解析器与出口归属一致 |
| 分流代理(PAC/规则) | 视规则 | 部分域名一致、部分不一致 |
| 企业内网 | 内网递归 | 解析器归属为企业或专线,需另行核对 |
| 浏览器 DoH 开启 | DoH 服务商 | 检测侧可能完全无观测 |
第四行值得单独说明:企业内网递归解析器通常对检测站点不可见(因为不向外网权威发查询,或经专线统一出口)。这不一定是问题,但意味着必须结合内网配置来解读,不能照搬个人环境的口径。
5.1 CDN 与就近调度带来的干扰
在分析解析路径之前,还要考虑 CDN 的存在。现代站点的解析结果往往由调度系统动态决定,因此:
- 解析结果因地区而异是正常的,不能把"不同地区返回不同 IP"当作异常;
- 权威侧可能只看到 CDN 供应商的解析基础设施,与终端解析器之间还隔着若干转发环节;
- ECS 会显著改变调度结果,开与关可能返回完全不同的节点。
这些因素不改变"解析路径归属是否一致"的判断逻辑,但会影响你如何解读具体的解析结果。把"调度差异"和"路径异常"分开,是避免误判的前提。
5.2 审计视角下的记录要求
如果检测的目的是合规留痕而不是个人排障,记录粒度需要更高。建议至少覆盖:
- 检测发起时间与结束时间(含时区);
- HTTP 出口的 IPv4/IPv6 地址、Origin ASN、运营商与 BGP 前缀;
- 递归解析器来源、解析器 Origin ASN 与运营商类型;
- 是否观测到查询,以及未观测到时的排查方向;
- 浏览器 DoH 状态、是否启用 ECS;
- 结论与依据,并注明"推测值"与"实测值"的区别。
这份清单的要害在于最后一条。审计场景最怕的是把推测当成实测:位置是推断的、归属是映射的、结论却写成了确定的。把数据来源与更新时间一并记录,结论才经得起复盘。
六、加密 DNS 对检测的影响
DoH(DNS over HTTPS)与 DoT(DNS over TLS)把解析请求放进了加密通道,对隐私是提升,对检测是挑战。
6.1 观测难度的变化
启用 DoH 后,解析请求表现为普通 HTTPS 流量,检测侧无法再从权威日志观测到"谁在解析"。这带来一个现实矛盾:越是隐私保护完善的配置,越难被外部检测验证。
6.2 浏览器侧的可控项
主流浏览器都提供了控制项,例如基于策略的 DnsOverHttpsMode(可取值 off、automatic、secure)。在做合规排查时,通常建议:
- 明确记录浏览器当前的 DoH 状态;
- 若使用
secure模式,解析器即为 DoH 服务商,此时应把"DoH 服务商归属"作为核对对象; - 若使用
automatic,行为依赖系统 DNS 能力,同一浏览器在不同网络下可能表现不同,结论必须标注环境。
6.3 检测策略上的调整
在 DoH 普遍启用的今天,只做"权威侧观测"已经不够。更完整的做法是多手段并用:既看权威侧是否收到查询,也看浏览器侧的 DoH 配置,必要时结合本机抓包确认实际解析器。多一个观测面,就少一分"未观测到"的模糊结论。
七、排障与加固建议
7.1 加固方向
- 让解析路径跟随访问路径:把系统或浏览器侧的 DNS 一并纳入代理或 VPN 通道,而不是只改 HTTP。
- 注意 IPv4 与 IPv6 分别处理:只配置了 IPv4 代理时,IPv6 往往仍走本地解析与本地直连。
- 核对分流规则:PAC 与规则文件中的域名列表要覆盖业务真实使用的全部域名,包括鉴权、静态资源与接口域名。
- 谨慎对待 ECS:如果业务对位置一致性敏感,应确认解析链路上是否传递了客户端子网。
7.2 验证与记录
加固后必须复测,并至少记录:检测时间、HTTP 出口(IPv4/IPv6 与 ASN)、解析器来源地址与 Origin ASN、是否观测到查询、浏览器 DoH 状态、是否携带 ECS。
实践中,把 HTTP 出口、WebRTC 候选与 DNS 出口三条通道放在同一个页面上对比会方便很多。DNSPup 的 DNS 泄露检测页面(https://dnspup.com/dns-leak/ )会为每次检测生成独立的随机权威域名,列出递归 DNS 查询来源、解析器位置与 Origin ASN,并与当前 HTTP IPv4/IPv6 出口逐项对照,同时明确标注"未观测到不等同于没有泄露"以及各项数据的来源与更新时间------这种把观测失败与判定结论分开的写法,对排障而言比一个简单的是否标签有用得多。
7.3 变更管理
DNS 配置最容易出现的问题不是"配错",而是"改了不知道"。建议把以下项目纳入变更记录:解析器变更、DoH 开关变更、分流规则更新、ECS 策略调整。每一项变更后都跑一次检测并归档结果,这样当业务出现地域异常时,才有基线可比。
八、常见误区
- "DNS 泄露 = 真实 IP 被公开":不准确。标准链路下权威侧看到的是递归解析器地址。
- "解析器地址和出口地址不同就说明泄露":不成立。两者本就不会相同,要比的是归属。
- "检测无结果就是安全":不成立。DoH、缓存、策略拦截都会造成观测盲区。
- "公共 DNS 一定更好":取决于业务。公共 DNS 在就近调度上可能不如运营商递归,且 Anycast 会让位置推断失真。
- "改了就一定生效":终端、路由器、浏览器三层都可能有 DNS 覆盖,需要逐层确认。
九、什么时候需要重复检测
最后补充一个使用频率上的建议。DNS 配置并非一次性工程,以下四种时点都建议重新检测,而不是只在出问题时才查:
- 网络环境切换后:从办公网切到家庭网络、从固定宽带切到移动热点,解析器归属几乎必然变化;
- 代理或 VPN 配置调整后:尤其是修改了分流规则、DNS 转发或协议栈偏好之后;
- 浏览器版本升级后:DoH 的默认策略随版本演进,升级可能悄悄改变解析行为;
- 业务侧出现地域异常时:例如登录验证、内容展示出现地区不符,此时 DNS 出口是优先排查项之一。
把重复检测变成例行动作,最大的收益是积累基线。有了与自己环境匹配的历史记录,"这次是不是和上次不一样"就不再需要凭感觉回答,而是可以直接比对字段得出结论。
十、结论
DNS 泄露检测要解决的问题,本质上只有一个:搞清楚你的解析行为是从哪个网络发起的,以及它是否和你以为的访问路径一致。
要做好这件事,三个环节缺一不可:
- 可观测的基线:用一次性随机权威域名排除缓存与预取干扰,让每次解析行为都可被唯一关联;
- 正确的对照口径:与 HTTP 出口比"归属"而非"地址",并区分 IPv4 与 IPv6、区分推测位置与注册归属;
- 诚实的结论表述:"未观测到"就写"未观测到",并补充下一步观测手段,而不是直接宣称安全。
在实际工作中,建议把 DNS 出口与本机 HTTP 出口、WebRTC 候选出口放在一起核对,形成"访问路径 + 解析路径 + 媒体路径"三线一致的判断框架。当三者归属一致时,环境的网络属性基本可以认为是自洽的;当其中任一条出现偏移,就有了明确的下一步排查方向。这样一套流程,比反复讨论"到底算不算泄露"要有价值得多。