WebRTC 会泄漏真实 IP 吗?三种模式怎么设?
结论先给:会漏,但要分清漏的是什么。过去大家说的「WebRTC 泄漏内网 IP」,在现代 Chrome 内核上已经基本被浏览器自己堵住了;真正需要你操心的是真实公网 IP。原因是 WebRTC 为了建立点对点连接,会走 UDP 直接去问一台公网服务器「你那边看到我的地址是多少」,而绝大多数代理只负责代理浏览器的 HTTP 流量,这个 UDP 请求就从本机的真实网络出去了。于是页面能同时看到两个公网 IP:HTTP 请求带来的代理 IP,和 WebRTC 报出来的真实 IP。挂了代理就用「替换」模式,这是唯一一个既不漏又不显眼的选择。
WebRTC 是什么,为什么它能绕过代理
WebRTC 是浏览器内建的实时通信能力,网页版语音视频通话、屏幕共享、一部分在线客服工具和平台后台的视频功能都靠它。它和普通网页请求最大的区别是:普通请求是「浏览器 → 服务器」,可以老老实实按你配的代理走;而 WebRTC 要做的是「你的电脑 → 对方的电脑」直连,为了省掉中间服务器的带宽,它必须尽量找到一条直接可达的路径。
要找直连路径,就得先把「我能被哪些地址找到」列个清单出来,这个过程叫 ICE(交互式连接建立,浏览器用来收集并测试所有可能连通地址的一套机制)。麻烦有两层。第一层是时机:收集地址这件事,网页脚本一调用就开始了,不涉及摄像头麦克风权限,因此不会弹任何授权框,你完全感知不到。第二层是通道:收集来的地址清单写在一份叫 SDP 的会话描述文本里,而这份文本页面脚本可以直接读;同时收集过程本身走的是 UDP,而 HTTP 代理和多数 SOCKS 配置管的是 TCP 上的 HTTP 流量。UDP 不受管,就绕开了。
// 页面只要这几行就能拿到候选地址,无需任何权限弹窗
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:你的STUN服务器:19302' }]
});
pc.onicecandidate = e => {
if (e.candidate) console.log(e.candidate.candidate);
// 输出形如:candidate:1 1 udp 1686052607 203.0.113.45 54321 typ srflx ...
};
pc.createDataChannel('x');
pc.createOffer().then(o => pc.setLocalDescription(o));
三种候选地址,泄漏程度完全不同
ICE 收集出来的每一条地址叫一个「候选」,每条候选都标着自己的类型。看懂这三种类型,就看懂了泄漏是怎么发生的。
| 候选类型 | 是什么地址 | 怎么拿到的 | 对你的影响 |
|---|---|---|---|
| host | 本机网卡上的地址 | 浏览器自己枚举网卡 | 内网地址、VPN 虚拟网卡地址;现代 Chrome 已做遮蔽 |
| srflx | NAT 映射后的公网地址 | 向 STUN 服务器发 UDP 询问 | 最关键的一条,可能暴露真实公网 IP |
| relay | 中继服务器的地址 | 经 TURN 服务器转发 | 暴露最少,但要中继带宽,通常是兜底选项 |
srflx 那一行是重点。STUN 是一台架在公网上的小服务器,它的全部职责就是把「我看到你的请求是从哪个地址和端口来的」原样回给你。这本来是为了解决 NAT(家用路由器把内网多台设备共用一个公网出口的机制)导致的「我自己也不知道我的公网地址是多少」的问题。但对我们的场景来说,这句回答就是一份真实公网 IP 的证明——只要这个 UDP 请求是从本机真实网络出去的,STUN 看到的就是你的真实出口,而不是代理的出口。
现代 Chrome 的 mDNS:内网 IP 那条路已经窄了很多
这一点必须说清楚,因为网上大量教程还停留在几年前的行为上。较新版本的 Chrome 内核处理 host 候选的方式变了:它不再直接写出 192.168.x.x 这样的内网地址,而是给自己注册一个随机 UUID 的 .local 主机名(通过 mDNS,即局域网内的多播域名解析),把这个名字填进候选里。同一个局域网内的对端能解析出来照样连通,而远端网页只看到一串类似 a1b2c3d4-....local 的字符串,拿不到你的内网地址。
所以「WebRTC 一定会泄漏内网 IP」这个说法在现代 Chrome 上已经不准确了。但有三个前提要记住:一,mDNS 只保护 host 候选,对 srflx 那条携带公网 IP 的候选完全无效——而对跨境电商场景来说,真正要紧的恰好是公网 IP;二,那串 UUID 本身是页面能读到的值,虽然不含地址信息,同一会话内仍可用于关联;三,这属于浏览器行为,随内核版本、系统环境、企业策略而异,不能假定所有环境都一样。结论没变:不要把「浏览器自己会兜着」当成配置理由,该设的模式还是要设。
三种模式:替换、禁用、真实
| 模式 | 页面会读到什么 | 适合谁 | 代价与风险 |
|---|---|---|---|
| 替换(推荐默认) | 公网 IP = 代理出口 IP,和 HTTP 看到的一致 | 所有挂了代理的窗口 | 几乎没有;功能正常,两边自洽 |
| 禁用 / 关闭 | 接口不可用,读不到任何候选 | 确认业务完全不需要 WebRTC | 「没有 WebRTC」在现代浏览器里少见;网页通话、部分客服与后台视频功能会失效 |
| 真实 | 本机真实网络的地址 | 不挂代理、本机网络就是要用的出口 | 挂了代理还用它,等于把真实公网 IP 摆在页面上 |
为什么默认推荐替换而不是禁用?直觉上「关掉就一定不漏」听起来更彻底,但这里的判断标准和其他指纹项一样:你要的是看起来正常,不是看起来空白。现代浏览器普遍支持 WebRTC,一台连 RTCPeerConnection 都没有的浏览器属于少数配置。加上真实的功能损失——网页版通话进不去、某些客服工具和平台后台的视频模块直接报错——禁用的性价比并不高。替换模式则同时满足两件事:接口该有的都有,报出来的地址和你的代理出口对得上。
「真实」模式的适用面很窄,窄到基本只有一种情况:你不挂代理,就用本机网络运营这一个环境。一旦挂了代理还留在真实模式,泄漏就是必然的——不是概率问题。
怎么选:按场景对号入座
- 挂了代理的常规窗口 → 替换。这是绝大多数窗口的答案,配完不用再想。
- 同一台电脑上多个窗口用不同代理 → 全部替换。每个窗口各自跟随自己的代理出口,这样横向比较时它们的公网 IP 才是分开的。
- 不挂代理、只运营本机这一个环境 → 真实可以接受,替换也不会更差。
- 业务里完全用不到任何实时音视频功能,且你已确认相关页面不依赖它 → 才考虑禁用,并且做好功能异常的准备。
- 用了浏览器扩展或系统级工具去「关闭 WebRTC」 → 先取消。客户端已经在管这一项,两套机制叠加容易出现「有的候选被改了、有的没被改」的半截状态,比任何一种单独设置都糟。
自检:两分钟确认没漏
- 把代理配好并检测通过,再打开这个窗口——先有 IP,才有得比。
- 访问一个能同时显示「HTTP 来源 IP」和「WebRTC 报出的 IP」的检测页面。
- 比对两个公网 IP:必须一致。一致说明替换模式在生效;出现两个不同的公网 IP,就是典型泄漏。
- 看局域网那一栏:显示为
.local结尾的随机名字,或者干脆是空的,都属于正常,不要误当成漏了。 - 换第二个检测页面复核一次。不同站点的 STUN 服务器和实现不同,单一来源的结论不够稳。
- 确认无误后记在窗口备注里。之后每次换代理,都要重新走一遍这个比对。
四个常见误解
- 「不点允许摄像头就不会触发」。收集候选地址不需要任何设备权限,页面脚本调用接口就开始了,全程没有弹窗。
- 「禁用最安全」。不漏是真的,但读不到 WebRTC 是比读到更少见的状态,还要付出功能代价。多数场景替换更合适。
- 「看到 .local 就是泄漏了」。恰好相反,那是浏览器的 mDNS 遮蔽机制在起作用,说明内网地址没有被交出去。
- 「WebRTC 设好就不会暴露真实网络位置」。它只堵住了这一条路。DNS 解析走的是哪条线路、时区语言和出口 IP 归属地对不对得上、代理本身干不干净,都是另外的问题。
最后补一个容易被忽略的点:这一项和代理是成对的。今天窗口 A 换了新代理,WebRTC 的替换模式会跟着新出口走,但你仍然应该重新比对一次——代理协议变了、或者新代理只支持部分流量转发时,实际结果可能和预期不同。把「换代理之后比一次 IP」当成固定动作,成本两分钟,能省掉很多事后排查。
这些内容不在本篇范围内
代理字段怎么填、三种认证方式的区别,看《代理怎么填?账号密码、白名单、提取链接分别怎么配》;代理连不上、检测超时怎么排查,看《代理连接失败、检测超时、显示 IP 不对怎么排查》;完整的指纹参数清单,看《比特浏览器能改哪些浏览器指纹?完整参数清单》;检测站怎么用,看《怎么验证指纹环境是否正常?用哪些检测网站》。本篇只回答 WebRTC 的泄漏原理和三种模式该怎么选。
