负责过互联网系统建设和质量保障的基本都会遇到一个问题——劫持,所谓劫持就是把请求通过技术手段引导到指定的服务器代理一遍,通俗点讲就是过一遍手,过一遍手可做的文章就大了,可以监听信息、缓存内容也可以篡改内容,甚至拿到用户的登陆权限,如果别有用心是可以做很多非法的事情的,其中也有一种合法的代理应用叫CDN加速,CDN的存在可以提高用户体验,提升网站的访问速度,但很多业务其实是不适合代理的,因此强硬的劫持代理可能直接导致系统不可用,或者出现各种异常,所以互联网服务提供商很忌讳劫持的事情,一旦碰到基本无能为力,只能在技术上想各种预案来规避。
那么为什么还是很多厂商要不顾风险做这个事儿呢?一个字“利”,简单说一下劫持后的挣钱方法,最常规的方式有两种,一是清洗流量加cache挣带宽费,二是内容篡改加广告,其他靠获取用户权限信息挣钱的明显违法,故很少见。清洗流量一般指将视频、图片等静态资源在网内指定的出口服务器存储一份,降低出网带宽赚差价,一些大中小运营商都在干,本来这个事情对用户是透明无感的,但由于很多cache厂家技术不行,不该劫持的也劫持了,导致很多请求劫持后无法响应,造成用户APP或者各种使用异常,有些浏览器打着云加速的旗号其实也是干的劫持缓存的事儿;加广告一般指劫持后对内容进行了篡改,追加了广告代码,如果是简单的html页面,nginx配置一下都是可以实现的,加广告这种方式相比更是不合规甚至违法的,所以现在劫持的事情很多都是在偷着干。当然不否认,对运营商而言还是有个为用户提速目的的,毕竟很多资源都在联通、电信上,其他运营商的网内用户每次请求要跨网,速度太慢,慢了用户就要流失。
劫持和引导的方式有很多,但不外乎5类,1是网内直接给用户分配自建私有的LocalDns地址,域名解析不走根域走自定义,2是通过forword方式将特定域名引导至私有自建Dns解析,同样不走根域走自定义,3是cname引导,通常作为cdn的接入方式,4是透明代理,将设备作为路由器的一跳串联到网络传输中,5是劫持污染,又分为Http劫持和DNS劫持(污染),劫持和污染在操作上一般会在入口链路上使用分光设备将流量复制一份,复制后的流量使用流量分析设备进行分析,将符合条件的域名或者请求进行处理,达到重新引导流量的目的。
对于1、2、3的方式基本是通过正常的方式配置引导,技术上不做解说,着重讲一下4、5。
1、DNS劫持(污染)
DNS一般用的是udp53号端口,udp其中的一个特点是没有验证机制,非常容易伪装,当系统将DNS查询请求发出后,系统会接受第一个返回的结果作为使用,其后的将会被抛弃,劫持污染就是利用了udp的这种特性。
在操作上,将劫持设备放在网内(运营商内部),更靠近网民,同时监听分光流量的DNS查询请求,当分析到符合要求的域名后(一般为预先设置的一份白名单),抢先伪装一个DNS查询结果回复给用户,由于不论是时延还是链路质量,网内的要比网间的快太多好太多,所以用户肯定会第一个收到劫持设备的DNS回复,将其后出网查询到的结果抛弃,所以就达到了劫持的目的,这时候请求就被顺利的引导到指定的设备上了。
特征:DNS污染的典型特征就是解析出来的IP地址非互联网系统提供的地址。
2、Http请求劫持
Http请求劫持是在http请求阶段进行的,此种方式没有改变Dns的解析,而是通过302/301重定向将请求引导到了指定的设备上,因为效率比Dns低而且技术上有跨域问题,一般在对时延不敏感的文件下载中使用,技术上同样利用了网内和网间的时延差做文章,下面看图详解一下这个过程。
根据上图,我们看一下整个过程,首先是客户端与源站建链发送http请求,与此同时流量分析设备分析到了这个请求,并读取了请求头,第2步在读取http请求并判断符合劫持规则后,伪装客户端向源站发送了reset标记,断开了客户端与源站的交互,第3步伪装原站向客户端发送重定向302,将请求成功引导到指定设备,第4步是客户端访问劫持代理服务器。
因为重定向时跨域改变了url,这里面需要设置一套规则,简单举个例子,比如说客户端要下载的是www.aaa.com/123.mp4,指定的cache设备是1.1.1.1,被劫持后会发一个http://1.1.1.1/www.aaa.com/123.mp4的302重定向给客户端,客户端收到这个url后再进行拆解代理。
特征:典型特征就是重定向,用curl看一下是否将请求重定向就可以了。
3、透明代理
透明代理是将代理设备作为中间网关串联到链路中去,作为网关其实说白了代理设备同时要开启路由转发,承担路由器的作用,假设代理设备是个cache,很多大的企事业单位为了节约流量,会在其出口上安装一台这样的设备,比如说原来需要买两个G带宽,在做了透明代理后只需要买1.5个G了,对于用户而言没有任何需要操作的,所以叫透明代理,而且比较难分析。
透明代理也有两种方式,都是基于iptable,一种是基于端口转发,将目的地址是80的请求,转发到本地启用的比如说8080的cache应用上,由cache应用处理后为客户提供服务,这种方式的弊端是有可能影响一些服务,因为80端口过来不一定全是http请求。另外一种是采用tcp旁路监听代理的方式tproxy,此种方式是非常好的,配置iptable的mangle表的PREROUTING链,对tcp的socket的连接打上mark标记,然后新建路由表让打过标记的tcp通过,监听目的端口是80的tcp通过tproxy代理至8080的cache应用上,由cache应用处理后为客户提供服务。
操作上,服务器要开启路由转发、开启iptable,要安装代理软件,然后进行相应的配置,当然在高可用性上要做到对路由的心跳,一旦代理服务器故障,直接跳过代理服务器到下一跳,保证业务的持续性。
特征:这种方式基本上无法排查,从外部很难找到证据。
4、排查和预防
1)排查
排查的目的是找到证据,说明请求被劫持代理了,常用的方式如下:
【dns篡改】在问题网络环境dig域名查找A记录,对比是否是互联网系统提供的ip地址,如果不是说明Dns解析被篡改了,具体是哪种方式改的,需要继续排查;
【dns篡改】Dns劫持是基于udp的特性来实现的,所以不使用udp测试就可以绕过劫持,公共的dns服务都是支持tcp的,所以可以用tcp的方式进行验证,具体命令是 dig +tcp ,两个结果做对比;
【dns篡改】如果分析后确定解析被篡改了,dig里面有个trace的参数,可以详细查询到dns的解析过程,帮助我们分析是哪个dns篡改了我们的解析,具体命令是 dig +trace ,很好用;
【http劫持】这个在排查很简单,只要在问题网络环境里curl -I看头信息是否被重定向了就可以,如果被重定向那就是被劫了;
【透明代理】看解析和url都是没问题的,但是在某个网络环境里就是异常,很有可能是这个原因,厂家代理技术不过硬,没能正常处理所有请求,这个时候可以拿问题和正常环境下的信息做多方面对比,比如head头信息,分别在问题和正常环境curl -I对比头部各字段信息,如果不一致,那么肯定是在中间某个环节给篡改了;
【工具推荐】有一些在线工具可以辅助我们拿到用户的信息,一旦遇到小白用户可以直接用,推荐腾讯华佗、阿里昆仑。
2)预防
说预防的原因是因为很难根除,只能尽量通过技术手段规避,有些预防的方式如下:
客户端类的应用可以使用httpdns,httpdns可以在一定程度上防止劫持,但对于https的业务牵涉到domain证书的问题,需要找方案解决;
大厂业务上尽量使用一个主域名,劫持的目的是为了在不影响用户功能使用的前提下盈利,大厂服务的主域名用户量大,在没有把握的前提下厂商一般不太会动手劫持;
盈利的方式是劫持后资源的缓存或者篡改,如果无法缓存或者篡改,也就没有了劫持的意义,所以业务尽量使用https证书,证书可以让劫持本身变的毫无价值,劫持厂商脑袋没进水是不会去花钱劫持https类业务的。
来源:oschina
链接:https://my.oschina.net/u/4375750/blog/3290568