自建CDN实战经验合集之下载劫持怎么办?

1. 防劫持概述

关于劫持的具体说明,之前有文章详细阐述,不多说了,有兴趣的可以戳:揭秘运营商黑产流量劫持技术细节剖析

下文主要阐述了自建CDN在对抗下载劫持中的一些努力和尝试。我们已经知道劫持主要分类两大类:

DNS劫持和HTTP劫持。而HTTP劫持最常见的就是3XX跳转劫持,JS劫持以及HTML劫持。

从用户下载资源的路径分析,劫持可能主要发生在三个位置:用户到CDN节点,CDN提供商内部,CDN提供商回源机。

2. 用户到CDN节点防劫持

2.1 DNS防劫持

正常DNS解析的流程是用户走localdns,通过运营商提供的递归DNS进行域名解析。而DNS劫持一般发生在LDNS(递归dns)这一层。

可以用来防止DNS劫持的一个办法是HTTPDNS和随机域名。

HTTPDNS简而言之是基于HTTP协议来请求域名对应的IP,而不是使用LocalDNS来解析服务器IP。客户端向HTTPDNS服务器提供的API请求域名对应的IP,服务器收到域名请求后,使用DNS ECS完整走一遍递归解析的流程(当前也是会有策略缓存),查询到对应的最有IP后返回给客户端。

随机域名,顾名思义在进行域名解析时配置泛匹配的域名。

通过api生成随机域名提供给给客户端,客户端解析随机域名获取服务器的IP地址

HTTPDNS需要客户端的配合调整代码修改解析方式。而浏览器之类的无法自定义解析方式的变更。因为HTTPDNS只能用于自己可以调整代码的客户端。

随机域名虽然不需要客户端调整代码配合,但是必须通过某种方式(api也好,按照特定规则生成随机域名)获取随机域名,必然会有一个固定域名走的是localdns(可能是通过api获取随机域名也可能是下载随机域名的生成规则)。

两者虽然都能在一定程度上减少甚至是杜绝dns劫持,但是httpdns走的http协议,而随机域名强制重新走一遍递归dns,两者都会导致解析时间过大,对于大文件下载影响不大,但是对于小文件资源的加载性能的影响可能是致命的。当然也可以通过预解析的方式来减小这种影响。

2.2 HTTP防劫持

HTTP劫持是指在传输过程中,劫持方伪装成目的服务器抢先给出了响应。虽然后面目的服务器也给出来响应,但是因为劫持方的响应抢先到达,使得客户端接受了劫持的响应而抛弃了正确的响应。有时候劫持方会完全拦截用户的请求,目的服务器没有接受到任何请求。

在HTTP劫持中,3XX跳转,JS内容篡改以及html内容篡改都可能会发生。目前看3XX跳转和JS内容篡改比较常见。

劫持方想要达成的目的是默默的赚钱,因此这就决定了劫持方不可能猖獗到劫持整个域名的http请求。一般是通过过滤识别http请求的特征码来判断是否要进行劫持。

那么加上https,我们至少有两种防劫持思路。

1.采用https协议加密请求

2.隐藏http请求的特征,例如使用对称加密算法加密整个url。

https可以说是防止劫持的终极思路,但是https多了ssl握手的过程,会耗费一定的时间和性能。必须要考虑到时间影响和CDN节点的性能影响。另外https一般分为两种,一种是传统https(合用证书),一种是https sni。

目前的主流是https sni,但是市面上还残留着一些老旧版本的浏览器,因此再选用的时候务必确认好具体的业务需求。

URL加密也是经常用来防止劫持的做法。市面上的各大手机应用商店都采用了这种做法。相较于https,url加密的兼容性更好,并且对CDN节点带来的解密额外负担可以忽略。但是url加密需要CDN节点的密切配合。

一般的做法是选中一种对称加密算法,调用加密后的url。用户向CDN节点发起请求,CDN节点会解密url,获取真实的url并且响应给用户。由于劫持方一般通过对url进行匹配决定是否进行劫持,因此这种url加密的方式也可以很好的防止劫持。

3. CDN提供商内部防劫持

CDN提供商一般会将直接提供给用户请求访问的节点称为边缘节点。但大多数CDN的边缘节点并非直接就回源机了,一般会有中间层,如果回源压力较大的话,可能会有多级中间层。

CDN提供商内部的劫持便是指发生在边缘节点到各级中间层之间的劫持。由于CDN提供商内部一般采用自建DNS回源,不会使用运营商的本地dns,基本不会存在dns劫持的情况。因此要考虑的主要是http劫持这块。并且由于劫持的内容可能会被缓存到cdn节点,进而导致访问这个CDN节点的用户都被间接劫持,因此CDN提供商内部发生的劫持影响范围更广,更加严重。

各家CDN提供商内部的防劫持方式各部相同,CDN内部完全可以打隧道,私有协议加密以及https加密各种方式来防止劫持。

一般比较常用的也是https加密,比较简单高效。至于url加密要考虑到缓存共享,并且加密的url一般是定期变化的,如果直接缓存加密的url的话会浪费缓存空间,降低命中率导致用户体验下降。当然也可以用户到CDN节点解密下,CDN节点回源加密下,但是会增加复杂度。

4. CDN提供商回源防劫持

处于安全性和灵活性的考虑,较大厂商的CDN源机一般是选择自建,而不是完全托管在CDN厂商。尤其是源机要防止一些代码特殊处理的时候。

因为CDN频道具体回源的IP都是CDN厂商后台配置,走内部DNS。因此CDN提供商回源机这块也几乎不存在dns劫持。

而http防劫持的方式也与CDN提供商内部房劫持类似。最简单可行的方式也是https,源机变动的较小。当然CDN提供商也可能提供其他的一些防劫持方案,需要源机进行一些配合修改之类。

5. 检测HTTP劫持的方法

在维护CDN过程中,确认http劫持的方式较为简单。可以直接请求测试,观察响应header,响应内容以及CDN节点的日志,三者对比基本就可以确定。

但是确认到劫持后,如何收集更多的证据,跟正确的运营商管局保障则比较麻烦。因为从用户到最终的目的服务器中间经过了很多跳的路由节点,任何一跳都有可能被劫持。

没有明确的证据,各省的运营商可能相互之间互相推诿,最终报障无疾而终。

其实结合网络层的TTL字段,我们可以大致判断出来劫持是发生在哪两跳路由之间。

正常情况下数据包初始发出的时候为了防止ip包在网络中的无限循环,会定义一个ttl,即最大路由转发次数。每经过一跳,该跳就会将ttl的值减一,如果ip包在到达目的ip前,ttl减少为的话,就会被路由丢弃掉。

我们基于上面的原理,可以发送一种特殊的http请求包,我们设置从ttl为1开始发送请求,然后逐渐增加。正常情况下终点跳前不应该有响应的,但是如果还未到达目的服务器这一条,就已经有响应了。我们就可以根据设置的ttl大小,结合mtr/tracert路由信息判断劫持发生的具体位置。

http_hijack_check检测工具:https://github.com/zhxiaom5/http_hijack_check

6. 总结

在用户通过CDN下载资源过程中,各个阶段都有可能发生劫持,要做好防劫持,必须各个阶段都有所准备,而不仅仅是用户到CDN节点这一段。

对于DNS劫持,比较有效的方式是随机域名和HTTPDNS。

而对于HTTP劫持的话,则可以采用URL加密以及HTTPS来处理。

在线上环境中必须考虑业务的实际需求,综合考量,搭配多种防劫持方式来取得最好的防劫持效果。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180504B1A4FT00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券