域名劫持大家并不陌生,从PC时代到移动互联时代,网络安全愈发重要,劫持方式更是层出不穷。现在到了智能客厅时代(意淫一下),如果说移动互联时代由于开放性和竞争性,大的厂商还是有良知的,比较注重口碑二字,但客厅由于其封闭性,无良厂商只手遮天,各类监控、各类弹窗广告、各类精简系统、各类系统级封杀等,导致客厅开发异常复杂,只有把主动权把握在自己手中,才能感觉到一丝丝安全。
传统的域名解析是一个系统调用,解析的结果可以说控制在运营商手中,也可能控制在厂商手中(无良厂商改系统),现在我们要把域名解析的主动权收到自己的手中,于是HttpDNS技术应运而生。
我们把客厅接口数据分为两部分:一部分是客厅业务接口,一部分是客厅CDN图片接口。因为作为一个视频APP,图片量是极大的,图片的请求量要远超业务侧接口的请求量,请求量越大,接入HttpDNS技术的效果应该更好,话不多说看结论。
图1展示了客厅业务接口返回码分布图,其中左图为未接入HttpDNS技术的接口返回码,右图为接入HttpDNS技术之后的接口返回码。我们重点关注错误码6和错误码7,错误码6是由于域名解析失败导致的接口错误返回码,错误码7是解析出的ip无法连接到主机导致的接口错误返回码,可以看出在接入了HttpDNS技术之后,由域名解析问题导致的错误(错误码6、7总和)降低了61%,效果非常明显。
图1 客厅业务接口返回码分布图
再来看一下接口耗时,图2展示了客厅业务接口耗时分布图,其中左图为未接入HttpDNS技术的接口耗时,右图为接入HttpDNS技术之后的接口耗时。可以看出在接入了HttpDNS技术之后,接口耗时降低了40%,效果非常明显。
图2 客厅业务接口耗时分布图
图3展示了客厅CDN图片接口返回码分布图,其中左图为未接入HttpDNS技术的接口返回码,右图为接入HttpDNS技术之后的接口返回码。可以看出在接入了HttpDNS技术之后,由域名解析问题导致的错误(错误码6、7总和)降低了82%,比业务接口的接入效果更加明显。
图3 客厅CDN图片接口返回码分布图
再来看一下接口耗时,图4展示了客厅CDN图片接口耗时分布图,其中左图为未接入HttpDNS技术的接口耗时,右图为接入HttpDNS技术之后的接口耗时。可以看出在接入了HttpDNS技术之后,接口耗时降低了43%,比业务接口的接入效果更加明显。
图4 客厅CDN图片接口耗时分布图
首先看一下什么是域名劫持。图5简单示意了域名劫持流程:当用户向Local DNS去请求某个域名的真实ip时,运营商的Local DNS服务器回复了一个假网站或内容缓存服务器的ip,最终导致用户访问无法访问到真实ip,从而出现异常。
图5 域名劫持流程图
是不是非常简单明了!而HttpDNS技术正是为了解决域名劫持应运而生的。下面就来看一下HttpDNS技术的实现原理。
图6 HttpDNS技术原理图
图6展示了HttpDNS技术的实现原理,主要分两步:
1.客户端向HttpDNS服务器发起请求(该请求为ip直连请求),获取与域名对应的一系列ip列表;
2.客户端从ip列表中选取访问延迟最优的ip,直接用此ip代替域名发送请求,这样就避免了Local DNS域名解析这一步骤。
总结HttpDNS技术的优势:
1.根治域名解析异常:由于绕过了运营商的LocalDNS解析,客户端的请求通过ip直连,彻底解决了域名劫持问题;
2.精准调度:HttpDNS能直接获取到用户ip,避免了DNS出口ip和业务出口ip不同网段问题;
3.减少网络延迟:通过本地缓存ip,可以有效减少域名解析时间,降低用户网络请求的平均耗时;
4.提升网络请求可控性和可靠性:我们采用的HttpDNS服务器依托腾讯庞大的ip地址库,利用腾讯公网交换平台的BGP Anycast网络,大大提高了网络请求的可靠性,同时是否走HttpDNS以及BGP IP的选择均由后台控制,增加了可控性。
说起来容易做起来难!任何一种技术的尝鲜都不是一蹴而就的,我们也是从无数的坑里面爬出来,才最终打造了一套适合客厅TV的HttpDNS技术架构。曾几何时在第一版上线的时候就遇到了线上问题,也经历了暂停升级、通宵处理,历经多个版本的不断完善,才从带血的坑里爬出来。
这儿分成三部分来介绍客厅TV-APPHttpDNS技术的接入过程:HttpDNS技术核心架构层、HttpDNS技术业务逻辑层和HttpDNS技术客户端容错处理。
无图无真相,图7展示了客厅HttpDNS技术核心实现流程图:
1.客户端接收到域名请求,查询是否已有该域名历史解析结果缓存,如果已有解析结果缓存则转步骤2,否则转步骤3;
2.检查该缓存是否过期,如果没有过期,则返回查询结果,域名解析成功,否则转步骤3;
3.如果没有解析结果或缓存已过期,则向HttpDNS服务器(119.29.29.29)发起域名查询请求,如果请求成功则转步骤4,否则赚步骤5;
4.域名查询请求成功,得到一组ip列表,通过ip优化选择最优ip并返回查询结果,同时更新解析结果缓存;
5.域名查询请求失败,为了容错,必须再用Local DNS请求一遍,无论是否成功均返回,完成整个查询流程。
图7 客厅HttpDNS技术核心实现流程图
整个查询流程定下之后,开始设计各个客户端模块,图8展示了客厅HttpDNS技术模块结构图,包括查询模块、数据模块、IP优选模块、BGP-IP更新模块以及其他模块等。
图8 客厅HttpDNS技术模块结构图
图9 域名请求示意图
图10 BGP-IP更新流程图
简而言之,上面描述了,给我一个域名,还你一个ip这个过程。那如何给我一个域名呢?这也是一件很有趣的事,详见业务逻辑层分析。
一切抛弃业务谈技术的都是耍流氓。几乎所有的APP都涉及网络数据传输,这就需要有多个业务接口进行网络请求,如请求首页数据、请求列表数据、请求图片资源等,无论你是采用系统网络请求或是建有自己的网络库进行网络请求,想把域名直接替换为ip,无外乎以下方式:
DNS HOOK技术通过拦截Android系统域名解析调用getaddrinfo请求,将其拦截到我们的HttpDNS方案之中,利用HttpDNS技术解析域名对应ip,再把解析出的ip作为返回值返回给getaddrinfo系统调用,从而完成域名解析过程。
我们的客厅APP就采用了DNS HOOK技术,主要有以下原因:
这儿再单独介绍下客厅业务为啥如此复杂:
于是Android侧发起的网络请求经过系统调用getaddrinfo,被拦截到HttpDNS技术方案之中,通过2.1介绍的HttpDNS技术核心架构层解析出域名对应的ip并返回给系统调用,从而完成整个HttpDNS技术的接入。
上面介绍了Android业务侧接口的域名解析实现部分,你可能会产生疑问,那WebView和CURL又该何去何从呢?
图11 三种域名解析过程对比图
图11展示了Android原生域名解析、WebWiew和CURL域名解析过程,从解析过程可以看出,Android原生域名解析和WebWiew域名解析,只是调用到的系统库不同,一个是Libjavacore.so库,一个是libchromium_net.so库,都可以通过DNS HOOK技术实现解析过程。
CURL方式比较尴尬,无法拦截到,可能水平有限没找到系统库。但方法是思考出来的,对于Native层的网络请求CURL,我们通过jni调用java侧域名解析方法InetAddress,该方法会调用到Android原生域名解析过程,通过DNS HOOK技术,采用自建的HttpDNS技术方案,把解析到的ip结果返回到Native层,再通过域名替换,从而完成CURL接入HttpDNS技术的方案。这种方案的优点是只用维护一份java侧的HttpDNS解析,不用在Native层又另外实现一套解析方案。
至此,我们解答了”如何给我一个域名?“这个问题,总结下这一实现方案的优点:
网络请求是APP的根本,一旦出现网络不通,整个APP就像失去了联系一样,无声的消失在开发人员的世界之中。而域名解析又是网络请求的一个根本所在,一旦域名解析出现问题,就会导致网络请求出现错误,从而失去一个用户。为此,在接入HttpDNS技术的过程中我们做了多重容错处理。
1. 全局配置是否走HttpDNS技术
这是整个HttpDNS技术是否接入的总开关,以防止出现特殊情况时我们可以整体关闭该技术的接入,走入系统处理流程之中。特殊情况如我们使用的腾讯公网BGP-IP出现不可用又没有备用IP时,这时候HttpDNS的解析一定是出错的,虽然技术本身可以保证最后一定走入到系统处理流程之中,但却浪费了一些解析的时间成本,故直接关闭整个HttpDNS技术的接入。
2.全局配置BGP-IP更新
一旦BGP-IP(HttpDNS服务器ip)不可用,HttpDNS的解析一定是出错的,这时候就需要有一个备用的BGP-IP来进行替换,从而走入正常流程之中。
3.预埋ip
通过预埋一些重要域名对应的ip列表,当解析出现错误的时候可以直接查找该域名是否有对应的预埋ip,如果查找到则采用预埋ip进行网络请求。预埋ip作为兜底处理,可以提高域名解析的正确率,但有可能出现该ip不可用或延时很长的情况。
4.域名自动过滤
我们的APP有需要外部依赖jar包,这些jar包中可能包含非常多的域名,然而有些域名我们可能不希望其也走入HttpDNS解析之中,于是提供了一个域名过滤的功能,只处理我们明确需要处理的域名解析。
5.特定域名解析失败一段时间内自动屏蔽功能
如果HttpDNS服务器出现对某个特定域名一直解析出错的情况,我们会缓存该域名的出错次数,一旦该域名解析出错三次,则禁止其在1个小时内再通过HttpDNS服务器进行解析,转而使用系统原生解析流程,从而消减解析耗时。
如果您觉得我们的内容还不错,就请转发到朋友圈,和小伙伴一起分享吧~