即使挂着 VPN,WebRTC 协议仍可能通过 STUN 请求暴露你的真实 IP 地址。本文介绍 WebRTC 泄露的成因、如何自测,以及切实可靠的防护方法。
WebRTC 泄露指的是:浏览器的实时通信功能会暴露你的真实 IP 地址——包括真实的公网 IP——即使你已经开启了 VPN。要阻止它,你可以禁用 WebRTC、将其限制为只使用 VPN 的网络接口,或者选择一款明确支持拦截 WebRTC 泄露的 VPN。下面我们将详细解释这个泄露是如何发生的、如何自行检测,以及在不破坏视频通话的前提下最安全的修复方式。
什么是 WebRTC,浏览器为什么要内置它
WebRTC(网页实时通信)是一项浏览器技术,让网页能够在两台设备之间直接交换音频、视频和任意数据——也就是点对点(P2P)通信——而无需任何插件。它支撑着浏览器内的视频会议、语音通话、屏幕共享和文件传输,例如 Google Meet、Discord 以及大量在线客服聊天窗口。
由于 WebRTC 让两个对端直接相连,而不是把所有数据都经由中央服务器转发,因此每个对端都需要知道对方在网络上的可达地址。这个「发现」过程正是泄露的根源。WebRTC 既不是恶意软件,也不是漏洞——它只是在做它被设计来做的事。问题在于,这套为视频通话寻找最佳网络路径的机制,同样可以把你的真实 IP 地址交给页面上的任意脚本。
ICE 过程:STUN、TURN 与候选地址收集
为了建立直接连接,WebRTC 使用一套名为 ICE(交互式连接建立) 的框架,其规范定义于 RFC 8445。ICE 会收集两个对端之间所有可能的可达方式,并按照该 RFC 定义的优先级公式对它们排序——主机候选优先,其次是服务器反射候选,最后才是中继候选——因此浏览器总会先尝试最直接(也最容易暴露信息)的路径,再退回中继方案。每一种可达方式都被称为一个候选地址(candidate)。
候选地址主要有三类:
- 主机候选(Host)——你设备的局域网地址(例如
192.168.x.x或10.x.x.x这类 LAN IP,有时还包括 IPv6 地址)。 - 服务器反射候选(Server-reflexive)——从外部看到的你的公网 IP,通过询问 STUN 服务器获得。STUN(NAT 会话穿越工具)服务器只是回复:「我看到你是从这个公网 IP 和端口连过来的。」这正是可能暴露真实 IP 的候选地址。
- 中继候选(Relay)——当无法建立直接连接时,通过 TURN 服务器转发媒体流的回退方案。TURN 服务器只是中转流量,不会暴露新的 IP,但会消耗带宽,因此仅在万不得已时使用。
危险之处在于,ICE 会主动且悄无声息地收集候选地址。一个网页可以创建连接、根本不去呼叫任何人,却依然能读取浏览器收集到的候选地址——包括 STUN 发现的公网 IP。
为什么 VPN 不一定能救你
下面这一点会让大多数 VPN 用户感到意外。当你连接 VPN 后,普通网页流量会通过 VPN 接口进行隧道传输,所以查询 IP 的网站会显示 VPN 的地址。但 WebRTC 的 STUN 请求是一条独立的 UDP 流。根据你操作系统的路由规则、VPN 的分流(split-tunnel)设置,以及浏览器绑定网络接口的行为,这个 STUN 请求可能会走你的真实网络接口,而不是隧道。于是 STUN 服务器报告的就是你的真实公网 IP,页面随即读取到它——完全绕过了 VPN。
换句话说,VPN 保护了你的 HTTP 流量,而 WebRTC 却悄悄泄露了你本想隐藏的那个 IP。如果你想确认 VPN 是否真正隐藏了你的地址,可以使用 BrowserInsight 的 VPN/代理检测 和 IP 情报 工具,看看外部世界实际观察到的是什么。
mDNS .local 混淆机制及其局限
现代 Chromium 系浏览器(Chrome、Edge)和 Firefox 针对本地 IP 暴露加入了一项缓解措施:它们不再暴露原始的 192.168.x.x 主机候选,而是替换为一个随机化的 mDNS 主机名,形如 a1b2c3d4-....local。这个 .local 地址对远程脚本毫无意义,因此你的局域网拓扑得以保密,而连接在本地网络上仍能正常工作。
这一领域的规范是 RFC 8828(「WebRTC IP Address Handling Requirements」)。它并没有强制规定 .local 这种做法,而是定义了四种 IP 处理模式,并规定每种模式最多可以暴露多少网络信息:模式 1 枚举全部地址,模式 2 使用默认路由及其关联的本地地址,模式 3 只使用默认路由,模式 4 强制走代理。随机 mDNS 名称则是各家浏览器为在主机候选上满足其中最严格的一端而共同选择的实现方式:浏览器在本地链路上公布一个随机名称,对外交出的是这个名称而不是地址,于是局域网 IP 本身根本不会离开你的机器。
这是一项实实在在的改进,但它有两个重要局限:
- 它只隐藏主机(本地)候选。 服务器反射候选按定义就是一个公网地址——它正是公网上的 STUN 服务器所看到的、你的数据包来自何处,因此根本没有本地名称可以替代它。你的真实公网 IP 不会被 mDNS 隐藏,而这恰恰是对 VPN 用户最要命的那种泄露。
- 它依赖浏览器和平台的支持。 较旧的浏览器、某些嵌入式 webview 以及特定配置,仍可能暴露原始的本地 IP。
所以,mDNS 减少了通过局域网地址进行的指纹识别,但它并不能防御公网 IP 泄露。
RFC 8828 真正能帮到 VPN 用户的地方在于模式 3。「只使用默认路由」意味着 WebRTC 只能使用操作系统本来就用于普通流量的那个接口——而在 VPN 开启时,这个接口就是隧道。于是 STUN 请求会从隧道发出,服务器反射候选报告的也就成了 VPN 的地址,而不是你的地址。下一节里那些浏览器开关,底层做的正是这件事。
泄露在代码里长什么样
触发候选地址收集并不需要什么特殊工具。任何页面都可以用 W3C WebRTC 规范 中定义的标准接口 RTCPeerConnection,仅凭几行 JavaScript 就能做到。下面这段代码创建一个对等连接,指向一个公共 STUN 服务器,并打印浏览器发现的每一个候选地址:
// 揭示 WebRTC 收集到的 IP 候选地址
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
// 强制浏览器开始收集 ICE 候选地址
pc.createDataChannel('leak-test');
pc.onicecandidate = (event) => {
if (!event.candidate) return; // 收集完成
const candidate = event.candidate.candidate;
// ICE 候选字符串的第 5 个字段包含 IP
const ipMatch = candidate.match(
/([0-9]{1,3}(\.[0-9]{1,3}){3})|([a-f0-9]{1,4}(:[a-f0-9]{0,4}){2,7})/i
);
if (ipMatch) {
console.log('候选类型:', event.candidate.type);
console.log('暴露的地址:', ipMatch[0]);
}
};
pc.createOffer().then((offer) => pc.setLocalDescription(offer));
如果 event.candidate.type 是 srflx(服务器反射),而打印出来的地址是你的真实公网 IP 而非 VPN 的 IP,那么你就存在 WebRTC 泄露。
如何检测 WebRTC 泄露
测试大约只需一分钟:
- 连接 VPN 并确认它已生效。
- 记下 VPN 声称分配给你的公网 IP——BrowserInsight 的 IP 情报 页面就会显示它。
- 运行 BrowserInsight 的 VPN/代理检测。它会在你自己的浏览器里执行上面这套候选地址收集,把 WebRTC 得到的公网 IP 与你的 HTTP 请求实际来源 IP 并列展示,两者不一致即判定为 WebRTC 泄露。(想看原始输出的话,也可以把上面那段代码粘贴进浏览器控制台。)
- 把 WebRTC 暴露出来的地址与你的 VPN IP 做对比。
如果 WebRTC 显示的 IP 与你的 VPN 一致,说明你受到保护;如果它显示的是另一个公网 IP——你家里或 ISP 的地址——那就是泄露。一个泄露的 IP 只有在真正能精确定位到你时才对追踪者有意义,而 IP 地理定位并不像许多人以为的那么精确——尽管通常足以揭示你所在的城市和 ISP。要交叉验证除 WebRTC 之外你的连接还暴露了什么,这一步可以和 DNS 泄露检测 搭配进行,因为 DNS 泄露和 WebRTC 泄露往往源自同一个根因:流量逃出了隧道。
各浏览器的缓解方法
没有一个开关能在所有地方一劳永逸地解决 WebRTC,因为每个浏览器的处理方式都不同。下表总结了实用的选项。
| 浏览器/平台 | 缓解方法 | 取舍 |
|---|---|---|
| Chrome/Edge(桌面端) | 没有内置设置项,IP 处理策略只能通过扩展来改。Google 自家的 WebRTC Network Limiter 会把它设为「只用默认公网接口」,也就是 RFC 8828 的模式 3,让候选收集只发生在隧道上 | 扩展可能影响部分视频应用 |
| Firefox | 打开 about:config,将 media.peerconnection.enabled 设为 false,彻底禁用 WebRTC | 会完全破坏 WebRTC 视频/语音通话 |
| Safari(macOS/iOS) | 稳定版没有面向用户的关闭开关。在 iOS 上这甚至不是「换个浏览器」能解决的问题——所有 iOS 浏览器底层都是 WebKit,换浏览器毫无用处,只能用能在系统层面拦截 WebRTC 泄露的 VPN | 可控性有限 |
| Brave | 内置设置:在隐私设置中将 WebRTC IP 处理策略改为「禁用非代理 UDP」——这是最严格的一档,相当于 RFC 8828 的模式 4 | 可能影响点对点应用 |
| 移动端(Android/iOS) | 使用带 WebRTC 控制的浏览器(Brave、Firefox),或使用在网络层拦截 WebRTC 的 VPN 应用 | 应用级 VPN 是移动端最可靠的方案 |
对大多数 VPN 用户来说,最干净的修复根本不是某个浏览器开关——而是选择一款桌面端和移动端都明确宣传具备 WebRTC 泄露防护、并在操作系统网络层强制执行的 VPN,让 STUN 请求永远无法逃出隧道。
禁用 WebRTC 与限制 WebRTC
彻底禁用 WebRTC(即 Firefox 的 media.peerconnection.enabled 路线)可以保证零泄露,但它会破坏所有浏览器内的视频通话、语音聊天和屏幕共享。对大多数人来说,这未免太激进了。
更好的平衡是限制 WebRTC,使其只使用 VPN 的接口——这正是泄露防护扩展或具备 WebRTC 感知能力的 VPN 所做的事。你既能保留可用的视频通话,又堵住了公网 IP 泄露。把「完全禁用」留给一个专门加固、且你从不在其中打电话的浏览器配置文件即可。
常见问题
使用 VPN 会自动阻止 WebRTC 泄露吗?
不一定。VPN 会隧道传输你的普通网页流量,但 WebRTC 的 STUN 请求可能会因路由和分流设置而走另一条路径、经过你的真实网络接口。许多优质 VPN 会额外加入 WebRTC 泄露防护,但你应当实测,而不是想当然。
禁用 WebRTC 会让网站打不开吗?
它只会影响那些用到 WebRTC 的功能——浏览器内的视频会议、语音通话、屏幕共享,以及部分点对点文件传输。普通浏览、视频流和绝大多数网站都不受影响。如果你依赖视频通话,请改为限制 WebRTC 而不是禁用它。
mDNS .local 混淆能让我高枕无忧吗?
它隐藏的是你的本地局域网 IP,这对减少指纹识别是有益的,但它不会隐藏 STUN 发现的公网 IP。对 VPN 用户而言最关键的那种公网 IP 泄露,并不受 mDNS 影响。
我怎么知道 VPN 是否真的隐藏了我的 IP?
把 VPN 声称的 IP 与各类服务实际看到的地址做对比即可。BrowserInsight 的 VPN/代理检测 和 IP 情报 会展示外部世界观察到的地址和网络细节,让隐藏的泄露一目了然。
结语
WebRTC 是一项实用的技术,浏览器默认内置它也是合理的,但它的候选地址收集过程可能在 VPN 之后依然暴露你的真实公网 IP。解决之道不是惧怕 WebRTC——而是理解 ICE/STUN 机制、测试自己的环境,并施加恰当程度的缓解:日常使用时把 WebRTC 限制在隧道内,或在加固配置文件中彻底禁用它。先测试,再根据你的上网方式选择合适的取舍。
推荐阅读:


