WebRTC支持的苹果隐私中继功能遭吐槽

最近对Safari的批评声不断,其中很多是有关WebRTC的。尽管社区已经出具了详细的错误报告以示对此事的积极关注,但还是有很多人抱怨其功能缺失和其他倒退的服务(详见Das-Inge Aas发表在webrtcHacks上的这篇文章)。造成该现象的一个根本原因是苹果巨长无比的发布周期和非公开的路线图。这使得该产品很难被提前测试以及反馈bug。另一个原因是,什么因素能推动发布以及什么不能推动发布并不清楚。iCloud隐私中继就是上述原因产生的一个典型案例。这项功能目前在WebRTC中已经不可用了。

iCloud隐私中继是iCloud+在iOS15中提供的新功能之一。更多详情可见这篇采访以及这篇苹果的支持资料。简而言之,隐私中继本应用于隐藏你的IP地址。苹果提供了这么一个代理服务,即苹果只知道你的IP地址,然后把请求转发给尚未确定的第三方内容供应商,由他们实际去建立连接。苹果知道你的IP地址,但不知道你在看什么网站。而网站供应商不知道你的IP地址,你对他们是保持匿名的。

隐私中继应该是这样工作的。但我们对上周公开发布的iOS 15版本做了一些快速测试,发现WebRTC的ICE(交互式连接创建)过程打破了隐私中继。稍后会向展示这个动作。但首先让我们回顾一下ICE和其意义。

WebRTC NAT 和防火墙穿越

WebRTC是一个端对端(p2p)协议。你的摄像头、麦克风、屏幕共享和数据流直接从你的web浏览器发送到另一个web浏览器。之所以使用端对端,是因为直接的p2p连接通常是最快的,而低延迟对于快速、交互类通信至关重要。

为了建立直接连接,浏览器需要知道对方的IP地址。但网络地址转换(NAT)和防火墙往往会阻止这类直接通信。此时ICE(交互式连接创建)就派上了用场。ICE是确保上述IP地址信息能在你和接收方之间传递的程序。最常见的方法之一是借助使用NAT或STUN服务器的遍历session。你的浏览器会测试[j1] STUN服务器,服务器用你的公共IP进行响应。然后你的浏览器得到这个数据,并将其作为协商过程的一部分。

WebRTC STUN返回你的公共IP地址

当你建立一个RTCPeerConnection时,你应该指定iceServers对象作为配置的一部分

如果你是新手,请参阅Chad的Kranky Geek视频以获得更详细的解释。YouTube

WebRTC IP泄露

这意味着你的私人IP地址也被暴露了吗?是的,确实如此,这是设计上的问题。这个话题在WebRTC中经常出现,我们也经常讨论这个话题(讨论详见此处)。

这种情况经常发生吗?实际上,我们可以使用Chrome Platform Status tracker进行大致估计。为了建立一个能真正交互的WebRTC连接,应用程序需要同时进行setLocalDescription和setRemoteDescription的调用。从统计数据来看,本地描述的调用频率要高于远程描述。

Chrome统计:setLocalDescription

Chrome统计:setRemoteDescription

两者差异很大:6%对0.3%。那么为什么一个应用程序要用setLocalDescription,而不是setRemoteDescription呢?如果你想追踪用户的本地IP地址,用于指纹识别,你就不需要setRemoteDescription了。造成这种较大差异的唯一原因是追踪。你可以通过在webrtc-internals / about:webrtc中搜索你不认识的网站来体会这种差异。

解决方法——mDNS

API 本身设计过程中没有考虑到这个问题。那么为了解决,就引入了 MDNS candidate。启用时会使用UUID的随机生成的地址–即eb93e835-73d6-4a13-b6f6-2be4f3dee256.local被使用,而不是你的IP地址。这些MDNS条目只能在本地网络上解决,但像文件传输这样的重要用例仍是被允许的。

顺便说一下,是苹果想出了这个好主意(另外,请问google能否更新一下你们安卓系统该功能的实现进度呢?)。

想了解更多信息,请看Fippo这个演讲

亲自测试隐私中继和WebRTC

如果 private relay 会保护 IP 地址隐私,那么苹果如何解释如下的实验结果?

关闭隐私中继

  1. 在你的iOS 15 iCloud设置中关闭隐私中继

  2. 点击https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

这是一个相当简单的测试。测试使用WebRTC向STUN服务器询问设备的公共IP地址。该操作通过UDP套接字完成,是WebRTC 支持NAT遍历的核心功能的一部分。

  1. 点击最下方“Gather candidates”按钮。

  1. 我们在每个用例下都能看到三个候选人——两个经MDNS混淆的主机地址,和一个通过STUN收集的服务器反射(srflx)。

打开隐私中继

  1. 现在返回,打开Private Relay,并重新启动Safari。

  2. 打开同样的WebRTC样本页面

  3. 再次点击“Gather candidates”。

可以看到,STUN服务器的那个srflx候选者是个大问题——因为那是你的真实IP地址! 搜索“我的IP地址是什么”,你的系统会显示Private Relay正在工作。看来苹果忘记了代理WebRTC STUN请求。

苹果在干嘛?

苹果有意识到这个问题吗?Reddit一个月前发现了该问题,而Safari技术预览版的发布说明在九月初提到了一个神秘的“WebRTC中继”功能。指向了Webkit git存储库中的两个提交:

这些提交比Reddit发布的讨论早了几周。

我们需要把libwebrtc使用的套接字抽象和Safari进行整合,这样当libwebrtc打开一个UDP套接字,并向服务器发送一个STUN数据包时就会被中继。我们也找到了这方面的提交,将问题追溯到了六月底。

[Cocoa] Migrate WebRTC UDP socket handling to NW API

那么,为什么iOS 15没有在发布之前,把WebRTC和隐私中继进行适当整合呢?

对WebRTC应用的影响

坦白讲,该功能是一个公开的测试版。也许苹果在隐私中继和WebRTC服务方面遇到了困难,所以还没有打开这个功能罢了。

这确实是有可能的。毕竟WebRTC应该是尽可能的端对端。对于输入敏感的低延迟流媒体,通过一个,而不是两个实体(在不同的组织中)来中继流量真的是个坏主意。我们希望苹果的中继服务器可以全面测试,保留WebRTC和ICE的标准属性,如5元组。他们还需要在处理每秒几十兆比特的流媒体比特率的同时,不增加太多的延迟或丢包。如果做不到,那WebRTC服务可能需要要求他们的用户在Safari中使用WebRTC时关闭隐私中继这个功能。

文章地址:Apple's not so private relay fails with WebRTC - webrtcHacks

原文作者:Philipp Hancke chad hart