无侵入的 SDK 接入方法摸索 在 DNS 优化的实践中,我们碰着最大的问题,倒不是计策层面设计问题,而是我们的 DNS SDK 运用到实际 App 产物业务上的姿势问题。 业内对 HTTP DNS 在实际业务中的接入方法多回收 IP 直连的形式, 即原本直接请求 ,此刻我们先挪用 SDK 举办域名理会,拿到 IP 地点好比 1.1.1.1,然后替换域名为: ; 这样操纵之后, 由于 URL 中 HOST 已经是 IP 地点,网络请求库将跳过域名理会环节,直接向 1.1.1.1 处事器提倡 HTTP 请求。 在实际操纵中,对付 IP 直连的方案我们踩了不少的坑。 首先,对付 HTTP 请求,回收 IP 直连的方案后,我们照旧需要举办的一个操纵是手动设置 Header 中的 HOST :
HTTP 协议相比拟力容易,只需要处理惩罚 HOST,那么 HTTPS 呢? 提倡HTTPS请求首先需要举办 SSL/TLS 握手,其流程如下:
客户端发送 Client Hello,携带随机数、支持的加密算法等信息;
处事端收到请求后,选择符合的加密算法,连同公钥证书、随机数等信息返回给客户端;
客户端检讨处事端证书的正当性,计较发生随机数并用证书公钥加密发送给处事端;
处事端通过私钥获取随机数信息,基于之前的交互信息计较获得协商密钥并通知给客户端;
客户端验证处事端发送的数据和密钥,通事后两边握手完成,开始举办加密通信;
在我们回收 IP 直连的形式后,上述 HTTPS 的第三步会产生问题, 客户端检讨处事端下发的证书这行动包括两个步调:
客户端用当地生存的根证书解开证书链,确认处事端的证书是由可信任的机构揭晓的。
客户端需要查抄证书的 Domain 域和扩展域是否包括本次请求的 HOST。
证书的验证需要这两个步调都检讨通过才气够举办后续流程,不然 SSL/TLS 握手将在这里失败竣事。 由于在 IP 直连下,我们给网络请求库的 URL 中 host 部门已经被替换成了 IP 地点, 因此证书验证的第二步中,默认设置下 “本次请求的 HOST” 会是一个 IP 地点,这将导致 domain 查抄不匹配,最终 SSL/TLS 握手失败。 那么该如何办理这个问题? 办理 SSL/TLS 握手中域名校验问题的要领在于我们从头设置 HostnameVerifier, 让请求库用实际的域名去做域名校验, 代码示譬喻下:
我们又办理了一个问题,那么 IP 直连下, HTTPS 的问题都搞定了吗? 没有,HTTPS 尚有 SNI 的场景要非凡处理惩罚。 SNI(Server Name Indication)是为了办理一个处事器利用多个域名和证书的SSL/TLS扩展。它的根基事情道理如下:
处事端设置有多个域名和对应的证书。客户端在与处事器成立SSL链接之时,先发送本身要会见站点的域名。
处事器按照这个域名返回一个符合的证书。
跟上面 Domain 校验的环境雷同,这里的网络请求库默认发送给处事端的 "要会见站点的域名" 就是我们替换后的 IP 地点。 处事端在收到这样一个 IP 地点形式的域名后将是一脸懵逼,找不到对应的证书,最后只好下发一个默认的域名证书返来。 接下来产生的是,客户端在检讨证书的 Domain 域时,怎么也查抄不通过,因为处事端下发的证书原来就不是对应该域名的。 最后 SSL/TLS 握手失败了却。
上述这个 SNI 场景下的问题,我们是否有步伐办理呢? 可以办理,需用客户端从头定制 SSLSocketFactory , 不外修改的代码相对较多,这里就不罗列了。 假如我们 SDK 要接入到 App 实际业务中,到 HTTPS SNI 场景处理惩罚这里,相信许多同学都瓦解了,接入的事情量其实也不低。 许多环境下大概就做了妥协,只有 Okhttp 场景才利用这个 SDK,因为 Okhttp 自己支持 DNS 替换,没有上面那些问题。 在美图的实践中,我们不只仅但愿 Okhttp 的请求才举办这个 DNS 优化,我们但愿在 App H5 页面加载、播放器播放等场景也能应用相应的优化。 在这样的需求下,IP 直连的接入方案带来的接入事情量其实不低,甚至需要窜改到部门轮子。 在最初的实践中,我们也简直实验了落实 IP 直连 到各个模块,然而纵然降服了改革的事情量问题,实际运行上照旧会有不少坑。 那么,有没有更符合的一种技能方案,可以或许低落 我们 DNS SDK 的接入事情量,也能分身各类利用场景,好比 HTTPS、RTMP 协议等? 基于这样的方针,我们在实践中实验摸索了一种对业务集成友好的无侵入式 DNS SDK 集成方案。下面我们以 Android 平台举办说明。 我们知道在 Java 层面长举办 DNS 理会的根基方法是挪用如下要领: