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

Source: https://ipvolt.com/zh/blog/proxy-leak-check-todetect
Markdown: https://ipvolt.com/zh/blog/proxy-leak-check-todetect.md
Language: zh-CN

[ipvolt 首页](https://ipvolt.com/zh.md) / [博客](https://ipvolt.com/zh/blog.md) / 用 ToDetect 检查代理 IP、DNS 和 WebRTC 泄露

分析
发布于: 2026-10-23
更新于: 2026-10-23
作者： ipvolt
阅读约 4 分钟

用 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 代理。德国移动网络的背景见[德国代理](/zh/guides/germany-proxies)。
- **本机自身的连接**：位于爱沙尼亚塔林的商业 VPN 出口，属于数据中心地址。
- **遮盖**：截图中的 IP 地址已遮盖，[结果文件](/downloads/proxy-leak-check-todetect/results.json)中的 IP 也已删除，文件列出了每次运行的计数和评分。

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

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

## 2. 检查网站看到的 IP

打开代理并重新加载 [IP Quality Check](https://www.todetect.net/ip/)。对照代理应有的情况检查四个字段：位置、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%](/media/blog/proxy-leak-check-todetect/leak-ip.png)
*通过 4G 测试线路的 ToDetect IP Quality Check，2026 年 10 月 23 日。IP 地址和前缀已遮盖。*

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

| 连接 | IP 类型 | 评分 | 显示的扣分项 |
| --- | --- | ---: | --- |
| 本机自身的连接（VPN，爱沙尼亚） | Datacenter | 68% | IP Usage Frequency -3%, VPS/IDC Provider -25%, Occasional ASN Organization Change -4% |
| 4G 移动代理（Vodafone Germany） | Mobile | 94% | IP Usage Frequency -3%, Regional ISP -3% |

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

## 3. 检查 DNS 在哪里解析

在代理开启时运行 [DNS Leak Test](https://www.todetect.net/dns-leak/)。它会列出为你的浏览器应答查询的 DNS 解析器。通过的结果是：解析器属于代理所在的网络，或者是你有意选择的解析器。失败的结果是：出现你自己 ISP 或你自己网络的解析器。

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

![通过代理的 ToDetect DNS Leak Test：两个 Vodafone Germany 解析器](/media/blog/proxy-leak-check-todetect/leak-dns-leak.png)
*两个解析器都属于 Vodafone Germany。顶部的客户端 IP 已遮盖。*

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

## 4. 检查 WebRTC

打开 [WebRTC Leak Test（WebRTC 泄露测试）](https://www.todetect.net/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](/media/blog/proxy-leak-check-todetect/leak-webrtc.png)
*页面根据代理的 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_udp` | 17 个中 0 个（一次运行） | 通过 |
| Chromium 普通窗口，同一参数 | 17 个中 13 个（两次运行） | 泄露 |
| Chromium 普通窗口，配置文件首选项 `webrtc.ip_handling_policy` = `disable_non_proxied_udp` | 17 个中 0 个（两次运行） | 通过 |
| Firefox 默认设置 | 17 个中 10 个（一次运行） | 泄露 |
| Firefox，`media.peerconnection.ice.proxy_only` = true | 17 个中 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 代理设置](/zh/guides/playwright-proxy-setup)。

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

- 把企业策略 [WebRtcIPHandling](https://chromeenterprise.google/policies/#WebRtcIPHandling) 设为 `disable_non_proxied_udp`。这样 Chrome 只有在所配置的代理支持 UDP 时才使用 UDP，否则通过代理使用 TCP。策略页面给出了 Windows 注册表位置以及 macOS 和 Linux 上的首选项名称。
- 安装 Google 的 [WebRTC Network Limiter](https://chromewebstore.google.com/detail/webrtc-network-limiter/npeicpdbkakmehahjeeohfdhnlpdklia) 扩展。其商店页面说明，“禁用非代理 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](/media/blog/proxy-leak-check-todetect/fixed-webrtc.png)
*Chromium 普通窗口加配置文件首选项：没有暴露提示，17 个服务器全部为“Not detected”（截图显示三个）。*

## 5. 检查时区

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

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

![ToDetect Timezone Detection：基于 IP 的 Europe/Berlin 与浏览器的 Europe/Vilnius](/media/blog/proxy-leak-check-todetect/leak-timezone.png)
*基于 IP 的时区跟随代理，浏览器的时区 ID 仍停留在本机设置上。*

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

![修改后的 ToDetect Timezone Detection：两个时区均为 Europe/Berlin，区域设置 de-DE](/media/blog/proxy-leak-check-todetect/fixed-timezone.png)
*修改后：浏览器的 IANA 时区 ID 为 Europe/Berlin，区域设置为 de-DE。*

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

## 6. 最后再看指纹概览

[ToDetect 首页](https://www.todetect.net/)把上述检查汇总成“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（机器人检测）](https://www.todetect.net/bot-detection/)页面在每次运行中都标记了 WebDriver 和 Dev Tool 异常，在 headless 运行中还标记了 Headless Chrome 异常，这对自动化浏览器来说属于预期情况。类似无痕模式的上下文和 headless 模式会额外带来指纹扣分，因此做 QA、广告验证或地理位置检查时，请在你实际工作要用的浏览器配置文件中测试。

## 我们没有测试的内容

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

## 检查清单

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

ipvolt 做这些检查是为了自己的上线前测试。服务仍在开发中，将于 11 月初开放访问。如果你想在开放时收到通知，请[加入早期访问名单](https://ipvolt.com/#waitlist-closing)。访问开放时发送一封邮件。仅此而已。

## 参考来源

- [Chromium: Proxy support in Chrome (net/docs/proxy.md)](https://chromium.googlesource.com/chromium/src/+/main/net/docs/proxy.md)
- [RFC 8828: WebRTC IP Address Handling Requirements](https://www.rfc-editor.org/rfc/rfc8828)
- [Chrome Enterprise policy: WebRtcIPHandling](https://chromeenterprise.google/policies/#WebRtcIPHandling)
- [Chromium policy definition: WebRtcIPHandling.yaml](https://chromium.googlesource.com/chromium/src/+/main/components/policy/resources/templates/policy_definitions/WebRtc/WebRtcIPHandling.yaml)
- [Chrome extensions API: chrome.privacy (webRTCIPHandlingPolicy)](https://developer.chrome.com/docs/extensions/reference/api/privacy)
- [Chrome Web Store: WebRTC Network Limiter](https://chromewebstore.google.com/detail/webrtc-network-limiter/npeicpdbkakmehahjeeohfdhnlpdklia)
- [Chromium source: content_switches.cc (force-webrtc-ip-handling-policy)](https://chromium.googlesource.com/chromium/src/+/main/content/public/common/content_switches.cc)
- [Chromium source: headless_web_contents_impl.cc](https://chromium.googlesource.com/chromium/src/+/main/headless/lib/browser/headless_web_contents_impl.cc)
- [Chromium source: renderer_preferences_util.cc](https://chromium.googlesource.com/chromium/src/+/main/chrome/browser/renderer_preferences_util.cc)
- [Firefox source: modules/libpref/init/all.js (media.peerconnection prefs)](https://github.com/mozilla-firefox/firefox/blob/main/modules/libpref/init/all.js)
- [Firefox source: StaticPrefList.yaml](https://github.com/mozilla-firefox/firefox/blob/main/modules/libpref/init/StaticPrefList.yaml)
- [ToDetect IP Quality Check](https://www.todetect.net/ip/)
- [ToDetect DNS Leak Test](https://www.todetect.net/dns-leak/)
- [ToDetect WebRTC Leak Test](https://www.todetect.net/webrtc/)
- [ToDetect Timezone Detection](https://www.todetect.net/timezone/)
- [ToDetect Browser Fingerprint Checker](https://www.todetect.net/)
- [ToDetect Bot Detection](https://www.todetect.net/bot-detection/)

## 第一时间了解 ipvolt 开放体验。

顺便一提

ipvolt 仍在开发中。留下邮箱，开放体验时我们只会通知你一次。

开放体验时仅发一封通知邮件，不发送其他邮件。

[申请抢先体验](https://ipvolt.com/zh/blog/proxy-leak-check-todetect#waitlist-blog-end)

[隐私政策](https://ipvolt.com/privacy)


## 相关文章

- [Python 3.15 网页抓取实测：哪些能装，哪些会坏](https://ipvolt.com/zh/blog/python-3-15-web-scraping.md) (分析, 2026年10月16日, 阅读约 4 分钟): 在没有 C 编译器的 Python 3.15 上，pip install scrapy 会失败，因为 brotli 没有 cp315 wheel。我们用 pip 和 uv 安装了 19 个抓取常用包。
- [日本价格解析：日元、全角字符与税込/税抜标签](https://ipvolt.com/zh/blog/japanese-price-parsing.md) (分析, 2026年10月6日, 阅读约 2 分钟): 解析日本价格字段，同时不丢失币种和计税基础。运行一套经过测试的 Python 夹具，覆盖全角日元、混合价格以及刻意设计的待复核用例。
- [SOCKS5 与 SOCKS5h 的区别：6 个客户端实测](https://ipvolt.com/zh/blog/socks5-vs-socks5h.md) (对比, 2026年10月4日, 阅读约 4 分钟): socks5:// 并不是在每个客户端里都表示本地 DNS。我们记录了 curl、Requests、HTTPX、aiohttp、Playwright 和 Node 在每种协议写法下发给 SOCKS5 代理的地址。

## 相关指南

- [在 Playwright 中配置代理](https://ipvolt.com/zh/guides/playwright-proxy-setup.md): 为 Playwright 浏览器上下文设置带认证的 HTTP 代理，保持测试状态隔离，并将页面导航与子资源请求的故障分开诊断。
- [德国代理：网络、城市与地区核查](https://ipvolt.com/zh/guides/germany-proxies.md): 结合最新的运营商与漫游背景、城市定位的局限、浏览器语言控制，以及一份实用的验收清单，评估德国代理并设计一次可复现的试用。
- [HTTP 与 SOCKS5 代理：按连接方式选择](https://ipvolt.com/zh/guides/http-vs-socks5-proxies.md): 对比 HTTP CONNECT 与 SOCKS5，理解 DNS 解析位置和 TLS 边界，并选择你的客户端和服务商实际支持的协议。

## 关于 ipvolt

来自 ipvolt 团队的技术分析。

ipvolt 尚未开放使用。

[阅读英文原文](https://ipvolt.com/blog/proxy-leak-check-todetect.md)
