机场CN机场CN
首页 >文章 >tech

深度解析 WebRTC 真实 IP 泄漏原理与硬核防御指南

Jichang Tech
更新于 2026-07-26

引言

在注重数字隐私的今天,许多用户习惯于通过配置系统全局代理或 VPN 来隐藏自己的真实 IP 地址。然而,常常令人感到震惊的是,尽管所有传统的 HTTP/HTTPS 流量都已经安全地穿透了隧道,一些测试网站却依然能够精准地读出用户的真实公网 IP 甚至局域网 IP。

这种“越权”行为的幕后黑手,往往是浏览器内置的 WebRTC (Web Real-Time Communication) 技术。本文将从协议底层深入探讨 WebRTC 导致 IP 泄漏的技术原理,解析 STUN/TURN 服务器在其中扮演的角色,并给出从浏览器到操作系统的硬核防御指南。

什么是 WebRTC?

WebRTC 是一项由 Google 主导并在 W3C 和 IETF 标准化的开源项目。它的核心目的是在不需要安装任何插件的情况下,使 Web 浏览器能够直接进行实时的语音、视频通话和点对点(P2P)文件传输。

传统的 Web 通信是 Client-Server 架构,客户端与服务器通信。而 WebRTC 为了降低延迟、节约服务器带宽资源,极力促成 Client-Client 的直接通信。要实现 P2P 通信,首先要解决的问题就是:如何让位于不同 NAT (网络地址转换) 后的设备找到彼此?

这就是 WebRTC 必须收集并暴露 IP 地址的根本原因。

IP 泄漏的元凶:ICE、STUN 与 TURN

为了在复杂的 NAT 环境下建立点对点连接,WebRTC 采用了一种名为 ICE (Interactive Connectivity Establishment,交互式连接建立) 的框架。ICE 会尝试所有的可能性来建立连接,它依赖于 STUN 和 TURN 服务器。

1. STUN 服务器的作用

STUN(Session Traversal Utilities for NAT)协议允许位于 NAT(或多重 NAT)后的客户端找出自己的公网 IP 地址、端口分配规则以及 NAT 类型。

当 WebRTC 应用初始化时,浏览器会向 STUN 服务器发送一个绑定请求。 STUN 服务器收到请求后,会将请求包源地址(即 NAT 映射后的公网 IP 和端口)作为响应内容发回给客户端。

[ Client (局域网 IP: 192.168.1.10) ]
       |
       | (发送 STUN 请求)
       v
[ 路由器 / NAT (公网 IP: 203.0.113.50) ]
       |
       | (转发 STUN 请求,源 IP 改为 203.0.113.50)
       v
[ STUN Server ]

STUN 服务器响应:“我看到你的请求来自 203.0.113.50”。 如此一来,浏览器就知道了自己真实的公网 IP,并将这个 IP 作为 ICE 候选者 (ICE Candidate) 记录下来。

2. TURN 服务器的作用

如果 NAT 类型极其严格(如对称 NAT),导致 P2P 穿透失败,WebRTC 会退而求其次,使用 TURN(Traversal Using Relays around NAT)服务器进行流量中继。尽管 TURN 会消耗服务器带宽,但在探测阶段,它同样参与了候选者的收集。

3. ICE 候选者的收集过程

WebRTC 的 RTCPeerConnection API 在建立连接时,会收集以下三种地址:

  1. Host Candidate (主机候选者):设备的真实物理网卡 IP 地址,通常是局域网 IP (例如 192.168.x.x10.x.x.x)。
  2. Server Reflexive Candidate (服务器反射候选者):通过 STUN 服务器获取到的公网 IP 和端口。
  3. Relayed Candidate (中继候选者):TURN 服务器分配的 IP 和端口。

在网页上,恶意脚本可以通过 JavaScript 轻松获取这些候选者:

const pc = new RTCPeerConnection({
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});

pc.createDataChannel("");
pc.createOffer().then(offer => pc.setLocalDescription(offer));

pc.onicecandidate = (event) => {
  if (event.candidate) {
    console.log("检测到 IP:", event.candidate.candidate);
    // 输出可能类似于: 
    // candidate:1 1 UDP 2113937151 192.168.1.10 52314 typ host
    // candidate:2 1 UDP 2113937151 203.0.113.50 52315 typ srflx
  }
};

这段简单的代码就能绕过网页原本的跨域和代理限制,直接向指定的 STUN 服务器发包(通常通过 UDP 发送),并将得到的公网 IP 与局域网 IP 汇报给网页。

为什么代理软件无法阻止 WebRTC 泄漏?

很多人有疑问:我明明开启了系统代理(如 HTTP Proxy 或 SOCKS5),为什么 WebRTC 还能把真实的公网 IP 漏出去?

原因在于代理的协议范围和浏览器底层的网络实现

  1. UDP 穿透:大多数早期的代理协议(如早期的 HTTP 代理和基础的 SOCKS4)仅支持 TCP 流量中继。而 WebRTC 的 STUN 探测和音视频数据流默认使用 UDP 协议。当浏览器发现代理不支持 UDP 时,为了保证 WebRTC 能够工作,它会直接绕过代理,通过本地网卡发送 UDP STUN 请求。这就直接暴露了真实公网 IP。
  2. TUN/TAP 虚拟网卡的优先级:即使使用了支持 UDP 转发的代理软件,如果软件没有完全接管操作系统的整个路由表(例如仅使用了浏览器的扩展代理,或是未开启 TUN 模式),WebRTC 依然可能扫描所有物理网卡,并将真实的局域网 IP 甚至多宿主主机上的非代理公网 IP 打包成 Host Candidate 发送出去。

深度防御指南

了解了 WebRTC 泄漏的深层逻辑,防御手段也就清晰了。我们需要从浏览器策略、网络层路由两大维度进行防御。

方案一:在浏览器层面禁用或限制 WebRTC

这是最直接有效的方式,适合那些不需要网页音视频通话功能的用户。

Google Chrome / Chromium 内核浏览器 Chrome 官方并没有提供一个一键关闭 WebRTC 的开关(因为他们是 WebRTC 的主导者),但可以通过安装扩展程序来限制 ICE 路由。 推荐扩展:WebRTC Network Limiter(由 Google 官方发布) 工作原理:修改浏览器的隐私策略 chrome.privacy.network.webRTCIPHandlingPolicy,将其设置为 default_public_interface_only 甚至 disable_non_proxied_udp。这会强制 WebRTC 流量只能走代理通道,或直接禁止 UDP 流量。

Mozilla Firefox Firefox 提供了直接修改底层配置的权限,无需安装插件。

  1. 在地址栏输入 about:config 并回车。
  2. 搜索 media.peerconnection.enabled
  3. 双击将其值改为 false。 这将从根源上彻底关闭 WebRTC API,从物理上断绝了泄漏可能。

方案二:网络层开启全局 TUN/TAP 接管

对于依赖 WebRTC 功能(如网页会议 Zoom, Google Meet)又必须保护 IP 隐私的用户,简单禁用 WebRTC 不可取。此时必须在网络层做文章。

  1. 使用支持全协议栈劫持的代理工具:放弃仅配置浏览器扩展代理,使用具有 TUN 虚拟网卡模式的现代网络工具(如 Clash 的 Tun 模式,或 WireGuard, OpenVPN 等)。
  2. 强制路由:TUN 模式会在操作系统层面建立一张虚拟网卡,并通过修改底层路由表,强制接管所有的 TCP、UDP 和 ICMP 流量。
  3. 消除物理网卡暴露:在正确的 TUN 配置下,WebRTC 获取到的 Host Candidate 将是 TUN 虚拟网卡分配的内网 IP(例如 198.18.0.x),而 STUN 探测请求也会被迫走隧道发送给远程代理服务器,返回的公网 IP 将是代理服务器的 IP,从而完美实现伪装。

总结

WebRTC 的初衷是为了构建一个更高效、低延迟的去中心化网络通信环境。然而,技术的双刃剑效应使得其 ICE 候选者收集机制成为了现代浏览器中最危险的隐私漏洞之一。

真正的安全防御不应依赖于单一的工具,而应建立在深刻理解底层协议的基础上。通过合理的浏览器安全策略配置与操作系统级别的路由接管(TUN模式),我们完全可以在享受 WebRTC 带来便利的同时,严守自己的数字隐私底线。