确定性陷阱:Mullvad 出口 IP 如何构建指纹特征向量
对于许多注重隐私的用户来说,VPN 是对抗追踪和监控的首用的防线。Mullvad 常因其对匿名性的承诺而受到赞誉,但最近的一项技术深度分析揭示了该服务在分配出口 IP 地址方面的一个令人惊讶的缺陷。Mullvad 并没有在连接时真正随机化分配给用户的 IP,而是使用了一种确定性的过程,这种过程可以被利用来对不同服务器位置的用户进行指纹识别。
出口 IP 分配机制
Mullvad 采用“垂直扩展”策略,为单个服务器提供多个出口 IP,以防止在热门网站上出现过度激进的 IP 封锁和速率限制。虽然这对可用性是有益的,但分配逻辑的实现方式却造成了安全漏洞。
研究表明,分配给用户的出口 IP 并非按会话随机化。相反,它是根据用户的 WireGuard 公钥确定性地选取的。虽然 Mullvad 官方应用会每 1 到 30 天轮换这些密钥,但使用第三方客户端的用户可能会发现他们的密钥——以及由此产生的出口 IP——根本不会轮换。
揭开模式:比例分析
为了测试这一点,研究人员绘制了几个服务器的出口 IP 范围。通过追踪跨越九个服务器的 3,650 个不同的公钥,他们发现了一个惊人的模式。尽管在这些服务器中存在数万亿种可能的 IP 组合,但公钥却始终被分配到仅 284 种唯一的组合中。
这一发现的关键在于“比例”。通过计算分配的 IP 相对于该服务器 IP 池起始位置的数值位置,并将其除以总池大小,可以得出一个一致的比例。
例如,如果用户在某个服务器的 IP 池中被分配到了第 81 百分位数的 IP,那么他们在连接到几乎所有其他服务器时,很可能也会被分配到该 IP 池中第 81 百分位数的 IP。这表明 Mullvad 正在使用一种基于种子的随机数生成器 (RNG),其中用户的密钥充当种子,而池大小则是上限。
Rust 实现缺陷
研究人员假设,这种行为是 Rust 编程语言中 random_range 函数的工作方式导致的(Mullvad 的后端和客户端均使用 Rust)。在许多 RNG 实现中,熵池不受提供给范围函数边界的影响。相反,RNG 会生成一个浮点数并将其用作边界的乘数:min + round((max - min) * float)。
由于对于给定的种子,无论范围如何,都会生成相同的浮点数,因此相对位置(百分位数)在不同的池大小之间保持不变。这很可能是一个开发者的误解——假设改变范围会导致不同的相对输出——而不是一个性的设计选择。
影响:关联攻击
这种确定性行为允许进行“关联攻击”。通过观察用户在不同服务器上使用的出口 IP,观察者可以推断出与该用户种子相关的浮点数。
虽然单个 IP 无法唯一地识别用户,但重叠的浮点数范围可以显著缩小身份范围。研究人员开发了一个工具来估算这些浮点数值,发现一组特定的 IP 可能会解析为仅由 0.34% 的用户群共享的浮点数范围。在拥有 100,000 名活跃用户的场景下,这会将用户的身份缩小到大约 340 人。
正如 Hacker News 上的一位社区成员所言:
"确定性出口 IP 让任何网站都能在不同会话之间构建持久的个人资料。你不是在消除追踪,而是在转移追踪者。"
对于一个论坛版主或拥有多个数据泄露事件中 IP 日志访问权限的国家级行为体,这意味着用户通过切换服务器来规避封锁或隐藏身份的行为实际上并不是匿名的。如果两个不同的账户使用不同的 Mullvad 服务器但解析到相同的狭窄浮点数范围,那么极有可能他们是同一个人。
如何保护自己
在服务提供商解决此问题之前,用户可以采取以下步骤来降低指纹识别的风险:
- 强制密钥轮换: 登出 Mullvad 应用以强制轮换您的公钥,这将改变用于 IP 分配的种子。
- 限制服务器切换: 避免在同一个公钥周期内频繁切换服务器,因为每个新服务器都会为观察者提供另一个数据点,从而使其能够细化您的浮点数范围。
- 使用 Tor 进行真正的匿名性: 正如一些技术批评者所指言, VPNs 是为隐私设计,而非完全的匿名性。对于需要高水平抵抗关联攻击的用户,Tor 网络仍然是金标准。