网站显示的是代理 IP,并不意味着所有网络请求都经过代理。页面可能通过一个出口加载,DNS 查询却走家庭网络,而 WebRTC 又通过第三条路径建立连接。
大家好!今天我们来看看 DNS 会暴露哪些信息,为什么出口所属运营商的 DNS 尤其重要,WebRTC 的域名解析如何单独发生泄漏,以及怎样配置 BlankTrail Proxy,让这些路径保持一致。我们还会解释,为什么 BlankTrail 使用自有的运营商 DNS 服务器数据库,其中的服务器只为各自网络的客户提供服务。
1. DNS 是网络特征中独立的一环
DNS 将域名转换为 IP 地址。程序向递归解析器发起查询,解析器从缓存返回答案,或向其他 DNS 服务器获取答案。权威服务器保存特定域名的记录。在家庭网络中,解析器通常由互联网服务提供商或网络管理员指定,但用户也可以选择其他解析器。例如,Cloudflare 文档就介绍了这一点。
加载页面和获取页面的地址是两项不同的任务。因此,仅仅设置 HTTP 或 SOCKS 代理,并不能确定计算机上每一个 DNS 请求的路径。

这里需要区分,究竟是谁观察到了请求。递归解析器能看到连接到它的源地址。域名的权威服务器通常看到的是递归解析器的 IP;额外的客户端信息可能通过 ECS 传递(EDNS0 Client Subnet,即一种允许 DNS 服务器传递部分用户 IP 地址的 DNS 协议扩展)。如果客户端直接访问权威服务器,权威服务器就能看到该连接的地址。RFC 9076解释了这些区别。
网站不会从普通 HTTP 请求头中获取你的 DNS 服务器列表。为了诊断,它可以让浏览器访问受控 DNS 区域中的唯一子域名,并将 DNS 观测结果与某个会话对应起来。这样的测试可以看出 DNS 请求来自哪里,以及是否携带 ECS。这就是 DNS 可以成为连接分析中额外信号的原因。
2. 为什么出口运营商的 DNS 更符合正常用户的网络特征
在普通家庭或移动网络中,IP 和 DNS 往往属于同一个网络环境:运营商分配地址,也提供解析器。过去,所连接的网络决定系统使用哪个 DNS,而如今应用也可以选择自己的服务。RFC 9076 关于解析器选择的章节介绍了这一背景。
假设 HTTP 请求来自某个运营商的住宅 IP,而 DNS 检测却显示,解析器属于用户在另一个国家的家庭网络运营商。对于会关联这些信号的系统来说,这就产生了一个问题:为什么同一会话中的两个请求属于不同的网络连接?
由此得到的实际结论是:对于住宅或移动网络出口,使用其所属运营商的 DNS,往往能形成更一致的网络特征。它与网站接收主要流量的连接相匹配。这是基于信号一致性的判断,并不是所有反欺诈系统都遵循的统一规则。
面向用户的运营商 DNS 与开放解析器列表并不是一回事
运营商的递归解析器可能只服务于自己网络内的客户:接受这些连接发来的请求,拒绝外部用户。开放解析器则会向任何能够访问它的客户端提供响应。对我们讨论的问题而言,这一区别很关键:用户网络的 DNS 符合该连接通常采用的地址解析方式。
公开的可用 DNS 服务器列表,无法还原出口运营商的 DNS 环境。 即使列表中的服务器位于所需国家,或者其 IP 注册在互联网运营商名下,它也可能对所有人开放。能够收到响应,并不意味着它就是所选网络正常使用的用户递归解析器。对于会比对 IP 与 DNS 基础设施的反欺诈系统,这种替换无法提供运营商 DNS 所带来的信号一致性优势。
甚至,随意选用其他网络中的开放解析器,可能比 Google Public DNS 更不符合正常用户的使用习惯。普通用户也会使用 Google DNS,因此这种选择有常见的日常解释。例如,APNIC Labs 在 2026 年 5 月的测量显示了 Google Public DNS 的广泛使用:全球有略低于 10% 的互联网用户使用它,而超过 20%(每五人中就有一人)的互联网用户将 Google DNS 配置为次要或备用解析器。相比之下,从住宅 IP 向另一个运营商名下鲜为人知的开放 DNS 发起查询,并不会因为两个地址位于同一国家就变得自然。这是对信号一致性的判断,不同反欺诈系统对这些信号的权重可能不同。
普通用户同样会使用公共 DNS。运营商可能把解析交给第三方,浏览器可能启用安全 DNS,企业网络也可能使用共享基础设施。因此,单凭 Google DNS 或 Cloudflare,不能认定用户正在使用自动化。但根据同一份 APNIC Labs 2026 年 5 月研究,Google DNS 的份额随地区不同,稳定在全球总流量的 6%–18% 左右,仍是全球最大的替代性公共 DNS 提供商。只有 Cloudflare 与它直接竞争。相较于使用自家运营商 DNS 的用户群体,这一比例仍然很小。在反欺诈系统看来,使用连接所属运营商的 DNS 会增加一定的可信度:真实用户中有 80% 以上使用此类 DNS,而机器人几乎不会使用它。
数据中心代理的情况可能不同:这种出口未必有合适的用户专用 DNS。此时,选择可用且信号一致的解析方式,比刻意让测试结果出现某个家庭网络运营商的名称更合理。
3. DNS 如何暴露 IP 或子网
直接访问解析器
如果 DNS 请求直接从家庭网络发出,解析器就能看到该连接的公网 IP。在家用路由器或 CGNAT 后,这个地址是相应出口的外部地址,不一定是计算机的私有地址。通过代理接收 HTTP 流量的网站不会自动获知完整的家庭 IP:它必须能够获取相应的观测结果,或借助其他泄漏渠道。不过,拥有反欺诈系统的大型网站会测量和检查这些信息。
ECS:DNS 请求中的子网信息
EDNS Client Subnet,简称 ECS,是 DNS 中用于传递客户端网络信息的附加字段。它有助于选择合适的 CDN 节点,但也可能把部分地址暴露给域名的权威服务器。RFC 7871建议,为保护隐私,应将 IPv4 地址截断到 24 位,将 IPv6 地址截断到 56 位。
例如,假设家庭 IP 为 198.51.100.42,ECS 可能包含 198.51.100.0/24。这表示一个包含 256 个地址的范围,而不是某一个具体 IP。不过,它仍然透露了客户端所在的网络,也可能帮助关联不同会话的观测结果。前缀长度取决于实现和配置;如果传递完整长度的前缀,就会暴露完整地址。

Google Public DNS 支持 ECS,也会检测权威服务器是否支持此功能。因此,不能认为每一个通过 Google 发出的查询都必然携带 ECS:其行为取决于 DNS 区域和服务器。参见 Google 的 ECS 指南。相比之下,Cloudflare 1.1.1.1 不会为普通域名发送 ECS;文档另行说明了 Akamai 诊断域名这一例外。
因此,“公共 DNS”这个标签本身无法说明请求中是否包含家庭子网。必须检查实际收到的 ECS。反过来,即使 DNS 请求经过了正确的隧道,如果客户端事先添加了其他子网信息,而转发过程保留了它,请求中仍然可能携带不属于出口的子网。
多条路径与备用 DNS
另一类问题来自多种设置的混用。浏览器使用自己的 DoH,系统服务使用路由器的 DNS,辅助进程又使用独立解析器。主路径出错时,备用路径可能接管。还需要单独考虑 IPv6:只控制 IPv4,并不能说明另一个协议栈的行为。
所以,某个请求中没有 ECS,或者某次测试显示了熟悉的解析器名称,都不能证明应用的所有请求已经受到保护。
4. WebRTC:先解析,再连接
WebRTC 用于浏览器之间的通信,以及音频、视频和数据传输。准备建立连接时,浏览器会收集 ICE 候选,也就是可能使用的地址和连接方式。这个过程可能使用 STUN 和 TURN 服务器。WebRTC 的对等连接指南介绍了这一机制。
这里有两个独立的阶段,需要分别检查。
阶段 1:获取 STUN 或 TURN 服务器的 IP
如果通过域名指定服务器,浏览器首先需要获取它的 IP。这是 WebRTC 内部的一次独立解析调用,并不是通过 HTTP 加载页面。在 Chromium 中,P2P 组件通过 HostResolver 创建 DNS 请求,这一点可以在 P2PSocketManager 源码中看到。
独立调用并不意味着 WebRTC 一定绕过浏览器的 DoH:不同组件可能共用解析服务。但具体路径取决于浏览器引擎、版本和设置。如果请求通过受保护路径之外的系统 DNS 发出,泄漏就会发生在 STUN 数据包发送之前。如果服务器直接用 IP 指定,就不需要为该地址执行这一步;重复测试时,缓存中的答案也可能使 DNS 请求不再出现。
可以使用受控 DNS 区域中的唯一 STUN 服务器名称进行检测。这样能看出,专门为 WebRTC 解析这个名称时采用了哪条路径。普通的页面 DNS 测试不能替代这项检查。
阶段 2:发送 STUN 请求
获取地址后,网络通信才开始。STUN 服务器会看到收到的数据包来自哪里,并将观察到的地址和端口返回给客户端。这是 STUN 的功能,而不是 DNS 的功能,具体见 RFC 8489。
如果数据包直接发出,服务器可能看到家庭或移动网络连接的完整公网 IP。为网页请求设置代理,并不能保证 WebRTC 也使用同一路径。例如,Chromium 中的 SOCKS5 用于 TCP URL 请求,并不用于转发 UDP,参见 Chromium 代理文档。STUN 检测绕过普通代理的风险也在 RFC 8828中单独讨论。

两种情况都可能发生:STUN 服务器名称通过正确的 DNS 解析,但数据包直接发出;或者 STUN 经过隧道,而此前的 DNS 请求却使用了家庭解析器。修复其中一个阶段,并不会自动修复另一个阶段。
在 JavaScript 层替换 WebRTC 地址,也不会改变已经发出的数据包的源地址。服务器侧的观测仍然独立。同样,本地 ICE 候选使用 mDNS 名称,是为了隐藏交换的候选中的本地地址,并不意味着外部网络路径已经受到保护。相关思路见 IETF 关于 mDNS 与 ICE 的草案。
5. 为什么仅有 DoH 还不够
DNS-over-HTTPS 会加密发往所选 DoH 服务器的请求。但加密不会替你选择出口。如果直接连接外部 DoH 服务,该服务就能看到直连的地址。如果请求携带 ECS,使用 HTTPS 本身也不会将它删除。
还需要检查出错时的行为。例如,Firefox 的默认保护允许回退到普通解析器。最高保护会在安全 DNS 不可用时显示警告;域名例外可以允许使用系统 DNS。参见 Firefox 的保护级别设置。
要控制解析路径,需要满足三个条件:选定服务器、通过正确的路径访问它,并且不出现意料之外的家庭 DNS 回退。浏览器的 DoH 设置只影响由它处理的请求,不会重定向计算机的所有流量或所有 WebRTC 连接。
6. BlankTrail Proxy 如何解决这些问题
BlankTrail 将任务分为两部分:选择正确的解析方式,以及将应用请求送达该解析路径。对于 WebRTC,还需要控制实际的网络通信。
vDNS:自有的运营商用户专用 DNS 数据库
BlankTrail 使用自有的运营商 DNS 服务器数据库,其中的服务器只为各自网络的客户提供服务。数据库覆盖超过 4,000 家运营商和 10,000 台 DNS 服务器。vDNS 会识别出口的运营商和地理位置,从数据库中选择合适且可用的解析器。
通过相应出口访问用户专用 DNS 基础设施,是这种方式的重要优势。公开的开放 DNS 列表包含对所有人响应的服务器,无法建立同样的出口与所属运营商常规解析器之间的对应关系。列表中的地址再多,也不会自动让网络特征变得更一致。
仅仅把用户专用 DNS 地址填入计算机设置还不够。从其他网络访问时,这类服务器可能拒绝递归查询,或根本不响应。请求必须通过属于其服务网络的出口到达它。这样,网站收到的主要流量来自代理 IP,DNS 观测结果也对应同一连接的网络基础设施。
如果没有可用的合适运营商 DNS,还可以采用其他方式:使用携带出口子网 ECS 的公共解析器、通过出口自行解析,或者将域名交给上游代理。选择取决于出口类型和所需的 DNS 策略。自行解析时,请求以出口 IP 到达权威服务器,这可以使源地址保持一致,但并没有还原普通运营商解析器的使用方式。
BlankTrail 默认启用 vDNS。可以在端口设置中选择它的工作模式:on_leak 在预检发现 DNS 泄漏后使用 vDNS,而 forced 始终使用它。使用 ECS 时,传递的子网将与所选出口一致。启用解析错误的严格策略,可防止连接继续走非预期路径。默认采用 auto 模式,优先选择运营商 DNS 服务器;如果没有适合出口的服务器,则尝试 Google、Cloudflare 和 Quad9 的公共 DNS。如果连公共服务器也无法工作,或过滤了目标网站的访问,接下来会沿处理链尝试通过出口本身解析,或将解析委托给代理,由代理在自己的网络侧尝试完成。
自有 DoH:将浏览器查询交给 BlankTrail
对于浏览器自行发出的 DNS 查询,BlankTrail 在产品端口上提供 DoH 服务器。可以将其地址填入安全 DNS 设置。之后,请求会通过出口,按照相应端口的 DNS 策略处理。
客户端传入的 ECS 会被删除,后续是否使用子网信息由端口设置决定。这样可以避免请求虽然进入了正确的隧道,却仍然携带家庭子网信息。
独立的浏览器配置文件可以分别使用不同端口的 DoH,各自对应不同出口。浏览器需要采用不会自动回退到系统 DNS 的严格模式。同时,还要单独检查具体浏览器的 WebRTC 解析是否进入同一条路径。
TUN:覆盖系统 DNS 和代理之外的流量
如果应用通过系统服务发出部分请求,或无法正确应用代理设置,可以使用 TUN 拦截。BlankTrail 在 Windows 和 macOS 上都实现了此功能,包括对单个应用的拦截。Windows 由已安装的系统服务负责拦截;macOS 则由 launchd 管理的系统守护进程负责,使用系统原生的 utun 隧道接口。可以选择整个系统或单个应用,并按端口设置拦截范围。详细信息请参阅拦截功能文档。
在 macOS 上选择应用时,会考虑其 .app 应用包,包括其中嵌套的辅助进程。对浏览器而言,这一点尤其重要:打开网络连接的可能是浏览器应用包内的独立辅助进程。拦截规则匹配的是应用,而不只是主进程的可执行文件;选择路径时,也会考虑父进程的规则。
两种平台都支持处理普通的系统 DNS 查询。在 macOS 上,BlankTrail 通过操作系统的网络配置设置系统解析器,共享服务 mDNSResponder 会使用这些配置。因此,仅仅在拦截应用列表中选中浏览器,并不意味着它的每个 DNS 查询都会被识别为浏览器进程的流量。
在单应用模式下,需要单独启用系统 DNS 捕获,并检查负责处理它的端口。如果应用使用不同端口和出口,请明确指定这个端口。此设置会影响共享的系统解析器:不同程序可以通过不同端口发送自己的连接,但不能自动把共享的系统 DNS 视为每个浏览器配置文件各自独立的 DNS 上下文。

这种拦截既可以覆盖通过系统解析器发出的 WebRTC DNS 查询,也可以覆盖 WebRTC 独立建立的网络连接。对于基于 UDP 的 STUN,出口必须支持 UDP,例如通过合适的隧道或 SOCKS5 UDP relay。普通 HTTP 代理无法满足这一要求。
如果受保护的出口不支持所需通信,正确的结果应是通信失败,而不是直接通过家庭网络发出。因此,WebRTC 能否正常工作与是否存在泄漏,需要分别评估。内置的端口绕行检测可以观察或阻止此类流量;vDNS、DoH 和 TUN 分别处理整体任务中的不同部分。
7. 如何阅读结果:审计界面中的示例
我们的 audit.blanktrail.com 检测工具以 HTML 展示浏览器报告,并以 JSON 返回会话数据。HTTP 客户端有单独的 /client JSON 响应。浏览器报告分别展示 DNS 观测、浏览器报告的 WebRTC 地址,以及服务器侧的 STUN 观测。
下面的三个教学场景使用真实审计页面的渲染函数生成,并保存为静态 HTML。IP 地址、国家、域名、查询次数和判定结果是为解释机制而设定的。这些不是启用 BlankTrail 前后的实际测量。第四个示例是来自真实 HTTP 客户端的匿名化响应,其来源单独说明。
三个场景中的预期出口均为 203.0.113.10,出口子网为 203.0.113.0/24。示例家庭地址为 198.51.100.42,家庭子网为 198.51.100.0/24。出口解析器表示为 192.0.2.53,家庭解析器表示为 192.0.2.54。这些地址取自示例地址范围,不代表真实连接。
示例 1:STUN 经过出口,但 WebRTC DNS 暴露了另一子网
DNS 表中带有 p1 的行对应普通页面探测:解析器和 ECS 与出口一致。带有 rtc1 的行对应 WebRTC 的域名解析:其中使用了另一解析器和家庭子网。当前脚本有四项此类探测,即 rtc1–rtc4,分别对使用不同传输方式的 STUN 和 TURN 名称进行解析。为了便于说明,示例只保留了两行 DNS 记录。

ecs_foreign 警告指出,某个子网并不包含主要出口地址。mixed_ecs 表示同一会话中出现了不同的 ECS。与此同时,WebRTC 表中是 203.0.113.10,STUN 服务器观察到的地址为 203.0.113.10:54000。也就是说,此场景中的 STUN 通信本身与出口一致,问题发生在此前的域名解析阶段。
实际检测时,需要查看每一行的具体内容:更换出口也可能导致不同的 ECS。探测名称有助于辨认哪个请求属于 WebRTC,但仅凭警告代码无法确定原因。
示例 2:DNS 一致,但 STUN 暴露家庭 IP
现在,两项 DNS 探测都通过出口解析器,传递的也是出口子网。但浏览器报告了 198.51.100.42,STUN 服务器也看到了来自 198.51.100.42:54000 的数据包。教学场景的判定中设置了 webrtc_foreign 警告。

此时只修复 DNS 没有意义:服务器地址通过正确路径获取,随后的连接却直接发出了。服务器侧观测独立于浏览器 JavaScript 填写的表格,确认了数据包的来源。这个场景需要控制 WebRTC 的网络路径,例如使用 TUN,配合合适的出口和 UDP 支持,或者阻止不受支持的通信。
示例 3:所有展示的通道都与出口一致
在第三个场景中,普通 DNS 和 WebRTC DNS 都使用出口解析器,ECS 描述的是出口子网,浏览器与 STUN 服务器也都显示出口地址。示例中设置了运营商 DNS 确认项 dns_resolver_native,用于展示对应的界面提示,并不表示已在真实数据库中验证这个示例解析器。

这是在所述场景中正确配置 vDNS、DoH 和 TUN 后的预期状态。不过,绿色结果只适用于该会话实际收集到的观测,不能证明每个应用、所有备用路径和未来连接的行为。如果 WebRTC 被阻止,也不能把没有 STUN 数据包当作数据包已通过出口的证据。
示例 4:HTTP 客户端执行 DNS 探测后的 JSON
/client 的操作流程不同。第一个响应包含 dns_probe_url 字段。需要使用同一个 HTTP 客户端、通过同一个代理访问该地址:唯一域名会触发 DNS 探测,其响应中包含 dns 数据块。下面展示的是此类请求的真实响应。客户端 IP、子网、PTR 和探测名称已被替换;结构、公共解析器及其他值均保留。

dns.resolvers 描述观察到的解析器,dns.client_subnets 则描述传递的客户端子网。此响应中包含 Google 公共解析器和 ECS。resolver_is_egress: false 表示观察到的解析器地址与 HTTP 客户端地址不同;这本身不能证明泄漏,因为解析器通常是独立的服务器。
响应中的空 findings 数组不能替代 DNS 分析,也不能证明没有 WebRTC 泄漏。普通 HTTP 客户端不会运行浏览器 ICE 探测。同样,http3.used: false 表示本次检测未使用 HTTP/3,而不是发生了 DNS 泄漏。
8. 如何自行复现检测
应在出口稳定时进行检测,避免将 IP 轮换与泄漏混淆。首先记录浏览器及其版本、代理类型、预期出口、vDNS 模式、DoH 设置和 TUN 范围。
- 打开浏览器检测工具,使用待测配置文件和所需出口。如有需要,选择中文,并等待“检测完成”状态。
- 核对测得的出口。它应与所选连接一致。分别考虑 IPv4 和 IPv6;如果轮换导致地址不一致,请在稳定出口下重新检测。
- 检查 DNS 表。对比普通探测名称与带有
rtc1–rtc4的名称。查看解析器、运营商和实际 ECS。如果某一行没有出现,代表没有观测到它,并不证明该路径已经受到保护。 - 对比 WebRTC 与 STUN。分别阅读浏览器信息表和服务器观测表。将 STUN 数据包来源与测得的出口进行核对。仅凭 JavaScript 显示的地址还不够。
- 修改设置并发起新检测。启用 vDNS、指定 DoH 或配置 TUN 后,使用“重新检测”按钮,再次等待检测完成。新会话会使用新的诊断名称。保存截图和 JSON,以便对比实际数据。
- 检查故障时的行为。所选 DNS 或隧道不可用时,不应启用直接联网的备用路径。通信被阻止与通信通过正确出口,是不同的结果。
浏览器会话 ID 显示在页面日志中的 会话 … 一行。完整 JSON 可通过 https://audit.blanktrail.com/api/session/<ID> 获取:将 <ID> 替换为本次检测的 ID。其中可以分别查看 observations、resolvers、client_subnets、webrtc、stun 和 verdict。上面的静态 HTML 示例由审计界面制作;复现检测时,无需寻找单独导出这种 HTML 的按钮。
使用 HTTP 客户端复现
请用真正要检测的客户端访问 /client。例如,使用 curl 通过 SOCKS5 访问时,运行以下命令,并将用户名、密码和端口替换为自己的值:
curl --silent --show-error --proxy socks5h://USER:PASS@127.0.0.1:20134 https://audit.blanktrail.com/client
在 Windows PowerShell 中,请使用 curl.exe 明确调用 curl。在 socks5h:// 中,字母 h 表示将域名交给代理解析,参见 curl 文档。这是 curl 的设置,不会控制其他浏览器的 DNS 或 WebRTC。
从第一个 JSON 中复制 dns_probe_url 的准确值,再使用相同参数发出第二个请求。请将下一条命令引号内的全部文本替换为获得的 URL:
curl --silent --show-error --proxy socks5h://USER:PASS@127.0.0.1:20134 "第一个响应中的_DNS_PROBE_URL"
保存第二个 JSON,检查其中的 dns 数据块。如果检测的是程序中的客户端,请通过该客户端完成两次请求:curl 的结果只能反映 curl 的路径。要检查 WebRTC,请回到浏览器检测工具。
9. 总结
一致的会话,始于对所有网络路径的控制。主要 IP、页面 DNS、WebRTC DNS、传递的 ECS 和 STUN 数据包来源,都应与所选连接一致。只检查页面 IP,会让其他通道仍处于未核实状态。
对于住宅或移动网络出口,所属运营商的常规 DNS 尤其重要。BlankTrail 的自有数据库包含只服务于各自网络客户的用户专用解析器。通过合适出口访问它们,就能使用该运营商用户所使用的 DNS 基础设施。公开列表中随意挑选的开放服务器,即使位于同一国家,也无法建立这种与连接的对应关系。
BlankTrail 通过组合配置解决这些任务:vDNS 选择解析方式并使用运营商 DNS 数据库,自有 DoH 服务器将浏览器查询交给它,TUN 则覆盖系统 DNS 和应用独立发出的连接。对于 WebRTC,服务器名称解析和随后的通信需要分别控制。如果出口不支持所需通信,应阻止该通信,而不能切换到直连路径。
应根据实际观测来判断结果:哪个解析器收到了查询,它传递了哪个子网,以及 STUN 数据包来自哪个地址。修改设置前后分别打开 BlankTrail 检测工具,等待每次检测完成,再对比报告。这样就能看出哪些路径已经保持一致,哪里还需要进一步配置。
