WebRTC 是浏览器内置的实时通信能力,视频会议、语音通话都依赖它。为了建立点对点连接,它会主动搜集本机的地址信息,并把这些“候选地址”交给网页脚本。在一些网络配置下,这个过程绕开了 VPN 或代理,让网站读到真实地址。

ICE 候选地址是怎么收集的
WebRTC 用 ICE 框架找到可用的连接路径,候选地址有三类:host 候选是本机网卡上的地址,srflx 候选是向 STUN 服务器发 UDP 请求后得到的公网映射地址,relay 候选是通过 TURN 中继的地址。网页脚本可以读取这些候选,不需要用户授权摄像头或麦克风。
为什么走了 VPN 还会泄露
全隧道的 VPN 下,STUN 的 UDP 请求也会走隧道,返回的是 VPN 出口地址,通常没有问题。泄露主要发生在三种情况:浏览器只配置了 HTTP 或 SOCKS 代理而 UDP 没有走代理;分流规则里 STUN 服务器的地址不在隧道路由内;系统有原生 IPv6 而隧道只承载 IPv4。
host 候选会暴露局域网地址吗
过去会。现在主流浏览器在没有获得媒体权限时,会用 mDNS 的随机 .local 名字替代真实的局域网地址,网页脚本只能看到一个无意义的字符串。真正需要关注的是 srflx 候选。
怎么验证有没有泄露
不需要第三方检测站点。在浏览器开发者工具的控制台里粘贴下面的脚本,会把收集到的候选逐条打印出来:
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
pc.createDataChannel('x');
pc.onicecandidate = e => e.candidate && console.log(e.candidate.candidate);
pc.createOffer().then(o => pc.setLocalDescription(o));怎么看懂输出的候选
每一条候选里有一个 typ 字段。typ srflx 后面的公网地址应该等于 VPN 的出口地址;如果出现了你的运营商分配的地址,就是泄露。typ host 的 .local 名称可以忽略,直接出现的私网地址则说明当前浏览器没有启用 mDNS 屏蔽。
场景与泄露风险对照
| 场景 | 是否可能泄露 | 原因 |
|---|---|---|
| 全隧道 VPN,IPv4 与 IPv6 都承载 | 低 | STUN 请求也走隧道 |
| 仅浏览器 HTTP 或 SOCKS 代理 | 高 | UDP 不经代理,直接从物理网卡发出 |
| 分流安装了部分网段 | 中 | STUN 服务器地址在隧道之外 |
| 隧道只承载 IPv4,系统有 IPv6 | 高 | IPv6 候选绕开隧道 |
缓解思路

最根本的办法是让物理网卡不能直接发 UDP,即在防火墙上只允许隧道网卡的出站,这样即使浏览器策略失效,请求也发不出去。浏览器层面可以调整 WebRTC 的 IP 处理策略:Firefox 在 about:config 里可以把 media.peerconnection.enabled 设为 false 完全关闭,Chrome 系浏览器可以通过扩展或企业策略把 WebRtcIPHandlingPolicy 设为 disable_non_proxied_udp。关闭 WebRTC 会影响视频会议类网页,需要权衡。
关掉 WebRTC 会有什么副作用
基于浏览器的视频会议、语音通话和一些点对点文件传输网页会无法使用。需要这些功能时,更合适的做法是保留 WebRTC,再用防火墙规则在系统层面确保流量都走隧道。




