一直以来,鉴于firefox对webrtc支持的前后兼容性和稳定性,本人都是用firefox测试webrtc,也一直跟客户建议在firefox上使用webrtc。但老是有人建议我使用Chrome,唉,不知道的还以为哥没用Chrome测试过webrtc,只是碍于其版本间差异过大,造成用户体验比较差没有用而已。据了解,在Chrome上测试webrtc,如今仍有不少人还在使用远古的6X Chrome版本,他们为啥不用新的Chrome版本?不是不愿用,而是不能用而已。今天,我来扒一扒他们为啥不能用最新的Chrome版本。抛开因为旧版openssl之前的漏洞,造成新版Chrome对ssl加密限制不谈,今天体验一下Chrome对webrtc中ip保护的摇摆。
自从浏览器支持了webrtc后,安全专家们就一直报告,浏览器有泄露ip的漏洞。OMG,这不是明摆的事情么,还用报告?webrtc的sdp描述初始就是包含真实ip,要是没有真实ip,通信怎么进行?要我说,这事很简单,加个webrtc的开关,默认禁用,特殊业务用户,用户能方便的打开就行了。但Google在漏洞报告的压力下,摇摆了很久。
先是在某些版本上,加上匿名ip的开关,有了这个开关,sdp里面的candidate成了这个样子:
a=candidate:0 1 UDP 2122252543 0.0.0.0 49202 typ host
这真是令人惊诧了,竟然搞出这么一道,你既然都是0.0.0.0了,还要candidate干啥?纯属脱裤子放屁。或许是感觉这种手段太让人捂脸了,于是Chrome在新版本中祭出了mdns大法。嗯,如果不考虑跨网络,只考虑单纯的一个局域网,这无疑也是一个可以接受的方案,只是这应用面也太狭窄了!跨网络怎么办?过nat怎么办?这可不是mdns能解决的,这也从侧面说明chrome面对ip泄露的指责,确实没有好办法解决了,只能先用mdns顶着了。
说回mdns,这是个什么鬼?仔细看,mdns是在dns前面多了个m,这应该很好理解了,就是Multicast DNS,协议跟dns一样,只不过采用了多播,端口5353,详情看rfc6762。既然是多播,那应用场景就是局域网了。Chrome设想的webrtc过程是这样的:Chrome(A端)向B端发起webrtc拨号请求,A端在产生offer sdp的candidate时,先产生一个uuid,用这个uuid加上.local的后缀,向mdns广播一条Response Record广而告之此local主机域名,然后,向B端发这样一条offer信令:
……
m=video 9 RTP/SAVP 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:211156821 1 udp 2113937151 6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local 55265 typ host generation 0 network-cost 999
……
注意看candidate行中的6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local,这地方原本是A端的真实ip。B端也要支持mdns,在A端Chrome通过mdns发出包含6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local与真实ip对应关系的Response Record后,B端就获得了这个对应关系,所以当B端收到这个offer信令后,就知道了candidate中所对应的真实ip,后续就按照常规的webrtc继续进行。在局域网下,这个设想很美好,在mdns的加持下,总算隐匿了ip,但实际上怎么样?我们来体验一把。
在windows端安装最新的chrome 90.0.4430.93,在CentOS7.9端安装最新版的FreeSWITCH 1.10.5,同时安装avahi和nss_mdns,配置使用mdns解析local域名,现在,来用Chrome注册到FreeSWITCH,并拨出3200,呼到FreeSWITCH默认的视频会议系统。如图:
是不是顺利的有点离奇?一个2x2视频会议画面清晰的呈现在Chrome网页上。我也没有想到能够一次成功,压抑住内心的喜悦,挂机,再来一次,OMG,呼不通了。看FreeSWITCH日志,有如下报错:
AUDIO RTP REPORTS ERROR: [Remote Address Error!]
说明6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local此时已经不能解析成功。。。
发生在Chrome身上的奇奇怪怪的事情多了,对这点小事我们也不必奇怪,我们可以通过抓包看出端倪,在打开Chrome打开webrtc页面第一次拨打3200时,前文说过Chrome发出了一条mdns的Response Record,我们看看这条命令的真面目:
注意看这条mdns消息,TTL为120s,问题来了,当120s过期后,Chrome没有续发mdns让6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local存活,只有当Chrome关闭时,发出了6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local失活的消息,所以当120s秒过后继续拨3200时,FreeSWITCH不能解析6978e6f5-5b1a-43bf-a77c-6d6cb694a25f.local,呼叫不能继续。
结论,Chrome虽然增加了mdns解决ip暴漏的问题,但仍不成熟,需要后续继续更新。在当前Chrome版本下,为了临时解决Chrome 120s的mdns ttl问题,可以这样:
1、在服务端mdns更新120s ttl,让ttl在120s后不失活,等待Chrome关闭后的失活消息后再失活。
2、如果你“愿意暴漏ip”, Chrome这个版本增加了是否启用mdns的选项,#enable-webrtc-hide-local-ips-with-mdns打开chrome://flags关闭这个选项即可。
3、在FreeSWITCH代码上修改不能解析local域名的问题,绕过协商时的真实ip,只要呼通后Chrome能向FreeSWITCH发媒体,FreeSWITCH就能获取Chrome的真实ip