分析阅读约 4 分钟

如何用 ToDetect 检查代理是否泄露 IP、DNS 和 WebRTC

用 ToDetect 的免费工具检查浏览器代理是否泄露 IP、DNS、WebRTC 和时区,并以一条 4G 移动线路的实测结果为例。

本页内容

浏览器代理改变的是页面请求的来源。DNS 查询、WebRTC 连接和浏览器时区仍可能指向本机自己的网络。本文介绍如何用 ToDetect 的免费工具逐项检查,通过和失败分别是什么样子,以及哪些修复在我们的测试中确实有效。

示例来自 ipvolt 做过的一次真实测试:

  • 时间:2026 年 10 月 23 日,16:45 至 16:57 UTC。
  • 机器:一台运行 macOS 15.7.4 的 Mac。
  • 浏览器:Chromium 153 和 Firefox,由 Playwright 1.63.0 驱动,分别在 headless 模式和普通窗口中运行。
  • 代理:一个 Vodafone Germany 网络上的 4G 移动代理,我们用它做上线前测试,配置为带用户名和密码的 HTTP 代理。德国移动网络的背景见德国代理。
  • 本机自身的连接:位于爱沙尼亚塔林的商业 VPN 出口,属于数据中心地址。
  • 遮盖:截图中的 IP 地址已遮盖,结果文件中的 IP 也已删除,文件列出了每次运行的计数和评分。

1. 先在不使用代理时取得基线

先在关闭代理的情况下把每项测试跑一遍,了解你自己的连接是什么样子。我们在 ToDetect 的 IP Quality Check(IP 质量检测)上的基线是:位置 Tallinn,IP 类型 Datacenter,ASN 组织标记为 HOSTING,IP Quality Score 为 68%。DNS Leak Test(DNS 泄露测试)只显示一个解析器,即 VPN 的解析器,位于爱沙尼亚。

2. 检查网站看到的 IP

打开代理并重新加载 IP Quality Check。对照代理应有的情况检查四个字段:位置、ISP 和 ASN、IP 类型以及时区。

通过移动代理,页面显示 Berlin、ISP D2VODAFONE、ASN 3209(Vodafone GmbH)、IP 类型 Mobile、IP Abuse 为“No”、时区 Europe/Berlin、语言 German。

通过移动代理的 ToDetect IP Quality Check:Berlin、D2VODAFONE、IP 类型 Mobile、IP Quality Score 94% 通过 4G 测试线路的 ToDetect IP Quality Check,2026 年 10 月 23 日。IP 地址和前缀已遮盖。

评分由页面列出的扣分项构成,可以展开查看评分变化的原因:

连接IP 类型评分显示的扣分项
本机自身的连接(VPN,爱沙尼亚)Datacenter68%IP Usage Frequency -3%, VPS/IDC Provider -25%, Occasional ASN Organization Change -4%
4G 移动代理(Vodafone Germany)Mobile94%IP Usage Frequency -3%, Regional ISP -3%

差距主要来自 VPS/IDC Provider 这一项扣分。通过的标准是位置、ISP 和 IP 类型与你配置的代理一致;第 5 步再比较时区与浏览器。如果仍然看到你自己的 ISP 或城市,说明浏览器没有使用代理,在修好之前其他测试意义不大。评分反映的是 ToDetect 自己的数据库,把它当作参考信号之一即可。

3. 检查 DNS 在哪里解析

在代理开启时运行 DNS Leak Test。它会列出为你的浏览器应答查询的 DNS 解析器。通过的结果是:解析器属于代理所在的网络,或者是你有意选择的解析器。失败的结果是:出现你自己 ISP 或你自己网络的解析器。

通过代理时,解析器是 139.7.74.9 和 139.7.74.10,均显示为“Vodafone Germany, Germany”。基线中的爱沙尼亚解析器不再出现。

通过代理的 ToDetect DNS Leak Test:两个 Vodafone Germany 解析器 两个解析器都属于 Vodafone Germany。顶部的客户端 IP 已遮盖。

对 Chromium 中的 HTTP 代理来说这是预期结果。Chromium 文档写道“name resolution is always deferred to the proxy”(域名解析总是交给代理完成):主机名随 CONNECT 请求一起发送。DNS 泄露可能出现在 SOCKS4 上,或出现在连接前先在本地解析域名的 SOCKS5 客户端上,例如使用 socks5:// 而不是 socks5h:// 的 curl。这种情况见 SOCKS5 与 SOCKS5h。

4. 检查 WebRTC

打开 WebRTC Leak Test(WebRTC 泄露测试)。它会询问 17 个 STUN 服务器,你的浏览器看起来来自哪个公网地址。通过的结果是:每个服务器都显示“Not detected”或代理的地址。失败的结果是:出现红色的“WebRTC IP Exposure Detected”提示,并且 Public IP 字段中出现你自己的地址。

在默认设置下,两个浏览器都没有通过:

  • Chromium 默认设置:17 个 STUN 服务器中有 13 个返回了本机自身的地址(三次运行中,IPv4 为 11 或 12 个,IPv6 为 1 或 2 个)。其余 4 个显示“Not detected”。
  • Firefox 默认设置:17 个中有 10 个返回了本机自身的 IPv4 地址,4 个显示“Not detected”。其余 3 个显示 0.0.0.0,既没有显示本机的 IP,也没有显示代理的 IP;我们没有查明原因。

Chromium 默认设置下的 ToDetect WebRTC Leak Test:WebRTC IP Exposure Detected 页面根据代理的 IP 把连接定位在柏林,但 STUN 服务器返回了本机自身的地址(已遮盖):本次运行为 17 个中的 13 个。裁剪后的截图只显示其中三个。

原因在于传输方式。WebRTC 通过 UDP 发送 STUN 请求。标准 HTTP 代理只转发 TCP 连接,因此默认情况下这些请求会经由本机自身的连接发出,STUN 服务器看到的就是这个公网 IP。RFC 8828 描述了这种情况:如果允许直接访问互联网,“WebRTC's STUN checks will bypass the proxy and reveal the public IP address of the client”(WebRTC 的 STUN 检查会绕过代理并暴露客户端的公网 IP 地址)。

我们测试过的修复

浏览器和设置显示本机自身地址的 STUN 服务器结果
Chromium 默认设置17 个中 13 个(三次运行)泄露
Chromium headless,--force-webrtc-ip-handling-policy=disable_non_proxied_udp17 个中 0 个(一次运行)通过
Chromium 普通窗口,同一参数17 个中 13 个(两次运行)泄露
Chromium 普通窗口,配置文件首选项 webrtc.ip_handling_policy = disable_non_proxied_udp17 个中 0 个(两次运行)通过
Firefox 默认设置17 个中 10 个(一次运行)泄露
Firefox,media.peerconnection.ice.proxy_only = true17 个中 0 个(一次运行)通过

计数同时包括 IPv4 和 IPv6 地址。

命令行参数对 headless Chromium 有效,对普通窗口无效。Chromium 源码中,这个开关由 headless shell 读取,而普通 Chrome 读取的是配置文件首选项 webrtc.ip_handling_policy。我们没有找到说明该参数在普通窗口中会被忽略的文档,因此请把这看作实测结果,而不是有文档依据的规则。

我们实测的 Chromium 修复方法,是在启动前把该首选项写入配置文件的 Default/Preferences 文件。在 Playwright 中这需要使用持久化上下文:

js
import { chromium } from 'playwright';
import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

const dir = mkdtempSync(join(tmpdir(), 'leak-check-'));
mkdirSync(join(dir, 'Default'));
writeFileSync(
  join(dir, 'Default', 'Preferences'),
  JSON.stringify({ webrtc: { ip_handling_policy: 'disable_non_proxied_udp' } }),
);

const context = await chromium.launchPersistentContext(dir, {
  headless: false,
  proxy: {
    server: process.env.PROXY_SERVER,
    username: process.env.PROXY_USERNAME,
    password: process.env.PROXY_PASSWORD,
  },
});

PROXY_SERVER 保存代理 URL,包括协议和端口。客户端的其余配置见 Playwright 代理设置。

在 Chrome 中设置同一首选项的另外两种方法,我们没有测试:

  • 把企业策略 WebRtcIPHandling 设为 disable_non_proxied_udp。这样 Chrome 只有在所配置的代理支持 UDP 时才使用 UDP,否则通过代理使用 TCP。策略页面给出了 Windows 注册表位置以及 macOS 和 Linux 上的首选项名称。
  • 安装 Google 的 WebRTC Network Limiter 扩展。其商店页面说明,“禁用非代理 UDP”默认未启用,需要在 Options 页面中开启。

根据 Chromium 的策略定义和 chrome.privacy 文档,这两种方法控制的都是我们设置的那个首选项。采用其中任何一种后,请重新运行 WebRTC 测试。

在 Firefox 中,打开 about:config,把 media.peerconnection.ice.proxy_only 设为 true,让 WebRTC 流量只经过所配置的代理。在 Playwright 中,把它作为 firefoxUserPrefs: { 'media.peerconnection.ice.proxy_only': true } 传给 firefox.launch()。把 media.peerconnection.enabled 设为 false 会完全关闭 WebRTC。我们只测试了第一项设置,且没有加上第 5 步的时区选项。

修复后的 ToDetect WebRTC Leak Test:所有 STUN 服务器均显示 Not detected Chromium 普通窗口加配置文件首选项:没有暴露提示,17 个服务器全部为“Not detected”(截图显示三个)。

5. 检查时区

打开 Timezone Detection(时区检测)页面。它会把根据 IP 推断的时区与浏览器自身的时区 ID 进行比较。如果你要检查网站对代理所在地访客的表现,例如本地化页面或广告投放,两者应当一致。

代理开启、浏览器保持本机设置时,基于 IP 的时区是 Europe/Berlin,而浏览器的 IANA 时区 ID 是 Europe/Vilnius。也就是说,时区 ID 不一致。代理改变的是网络路径,而不是浏览器的时区设置。在我们的运行中,ToDetect 显示两者的 UTC 偏移相同,只有时区 ID 不同。

ToDetect Timezone Detection:基于 IP 的 Europe/Berlin 与浏览器的 Europe/Vilnius 基于 IP 的时区跟随代理,浏览器的时区 ID 仍停留在本机设置上。

随后在 Chromium 中,我们在第 4 步的 launchPersistentContext() 选项里加入了 timezoneId: 'Europe/Berlin' 和 locale: 'de-DE'。“修复后”的截图使用的就是这套组合设置。之后两个时区都显示为 Europe/Berlin。

修改后的 ToDetect Timezone Detection:两个时区均为 Europe/Berlin,区域设置 de-DE 修改后:浏览器的 IANA 时区 ID 为 Europe/Berlin,区域设置为 de-DE。

在没有自动化的普通浏览器中,时区来自操作系统:修改系统时区,并在浏览器设置中设定语言。我们没有测试这种方法,因此修改后请再检查一次页面。

6. 最后再看指纹概览

ToDetect 首页把上述检查汇总成“Browser Fingerprint Consistency”(浏览器指纹一致性)评分,ToDetect 表示该评分“does not represent a definitive pass or fail result”(并不代表最终的通过或失败结果)。在使用持久化配置文件的 Chromium 普通窗口中,按页面显示,默认设置下为 65%,完成 WebRTC 和时区修改后为 87%。Timezone Anomaly 和 WebRTC Alert 扣分项消失了。剩下的 WebDriver 和 ClientRect 扣分来自自动化测试浏览器;Language Anomaly 也仍然存在,我们没有查明是什么触发了它。

Bot Detection(机器人检测)页面在每次运行中都标记了 WebDriver 和 Dev Tool 异常,在 headless 运行中还标记了 Headless Chrome 异常,这对自动化浏览器来说属于预期情况。类似无痕模式的上下文和 headless 模式会额外带来指纹扣分,因此做 QA、广告验证或地理位置检查时,请在你实际工作要用的浏览器配置文件中测试。

我们没有测试的内容

我们没有测试浏览器中的 SOCKS5(Chromium 不支持对 SOCKS5 代理使用用户名和密码登录)、Safari、Edge、移动浏览器,也没有测试会话期间的 IP 轮换。这些结果只描述一条线路、一台机器和一天的情况。

检查清单

  1. 在关闭代理时记录基线:IP、ISP、IP 类型和 DNS 解析器。
  2. 开启代理后,确认 IP 检查显示的是代理的位置、ISP 和 IP 类型,而不是你自己的。
  3. 确认 DNS Leak Test 只列出代理网络的解析器或你选择的解析器。
  4. 运行 WebRTC Leak Test。如果出现你自己的地址,把 Chrome 的 webrtc.ip_handling_policy 首选项设为 disable_non_proxied_udp,或把 Firefox 的 media.peerconnection.ice.proxy_only 设为 true,然后重新运行。不要在普通窗口中依赖命令行参数。
  5. 如果你的测试依赖代理所在地,请让浏览器的时区和区域设置与之一致(使用 Playwright 选项;在普通浏览器中则修改系统时区和浏览器语言),然后重新检查 Timezone Detection。
  6. 阅读指纹扣分项,把代理造成的扣分与测试环境造成的扣分区分开。
  7. 每次修改后,在你实际要用的浏览器配置中重新运行所有测试。

ipvolt 做这些检查是为了自己的上线前测试。服务仍在开发中,将于 11 月初开放访问。如果你想在开放时收到通知,请加入早期访问名单。访问开放时发送一封邮件。仅此而已。

参考来源

  1. Chromium: Proxy support in Chrome (net/docs/proxy.md)
  2. RFC 8828: WebRTC IP Address Handling Requirements
  3. Chrome Enterprise policy: WebRtcIPHandling
  4. Chromium policy definition: WebRtcIPHandling.yaml
  5. Chrome extensions API: chrome.privacy (webRTCIPHandlingPolicy)
  6. Chrome Web Store: WebRTC Network Limiter
  7. Chromium source: content_switches.cc (force-webrtc-ip-handling-policy)
  8. Chromium source: headless_web_contents_impl.cc
  9. Chromium source: renderer_preferences_util.cc
  10. Firefox source: modules/libpref/init/all.js (media.peerconnection prefs)
  11. Firefox source: StaticPrefList.yaml
  12. ToDetect IP Quality Check
  13. ToDetect DNS Leak Test
  14. ToDetect WebRTC Leak Test
  15. ToDetect Timezone Detection
  16. ToDetect Browser Fingerprint Checker
  17. ToDetect Bot Detection

标签:ProxiesTroubleshooting