春节前各家浏览器厂商不失时机的推出了“春节专版”。这些林林总总浏览器的共同特点,是集成了一位网友iFish(木鱼)的“订票助手”插件。这个插件的早期版本使用GitHub的Raw File服务作为CDN,并对返回403错误代码的请求使用非常暴力的5秒重试。于是,在1月15日第一个订票小高峰到来的时候,GitHub被间接的DDos攻击。
GitHub的运维工程师Jesse Newland在发现服务器负载异常之后,不得不禁用了这个代码所在Repo的Raw服务,并在Repo里报告了一个issue —— 他发现12306引用了这个Repo里的一个资源,由于访问量巨大,这个资源对GitHub的服务产生了负面的影响,希望有人可以联系到12306的工程师去除这个引用。
身在大洋彼岸的GitHub工程师在解决了GitHub的服务问题之余,显然不太清楚中国的两点情况:
- 春运是什么,12306是什么
- 12306的工程师是不可能被联系到的
大家的质疑,存在于两点:
- 为什么一个浏览器插件需要从GitHub引用资源?
- GitHub的负载能力这么弱吗?
第一个问题,还是让插件作者木鱼自己来解释:
引入自动更新。
由于12306订票助手是个很特殊的东西,依赖于铁道部的网站而存,并且其运行极度依赖网站本身的功能以及页面结构,所以随着铁道部的改进,很容易失效(虽然他们的前台样子从开始到现在,一年多了几乎就没变过……他喵的为什么我又要用年做单位说时间,真伤心)。因此为了保证功能的正常,订票助手在很早的版本开始就引入了自动更新机制(1.4开始)。最开始的更新都是放在自己网站上的,并且区分了Firefox和Chrome。
最初的助手是以UserScript的模式出现的,调试在Firefox下调试。在Firefox下时,Scriptish提供了支持跨域的GMxmlHttpRequest功能,可以直接用ajax访问我的网站。但是在Chrome下,则没有这样的便利,不支持跨域ajax,所以用的是引入script脚本的方式检测更新。在后来Firefox和Chrome分支完全合并后(最开始针对不同的浏览器分离的,后来发现同步实在太麻烦了),舍弃了一些特异的功能(如GMxmlHttpRequest),为一些功能做了适配(如桌面通知),更新也就用下来了。
但是后来不知道什么时候开始,这个更新机制突然失效了。为啥呢,这要从另一件事开始说起。
那就是12306的HTTPS。
作为一个日点击14亿的网站,网宿科技的CDN还是很给力的,根据我收集到的资料,其加速节点上百个。但是,作为一个订票的网站又要CDN的,为什么会用HTTPS协议还是一个自签发的根证书,实在太让人费解。任何一个了解网络知识的人都知道,HTTPS协议下服务器的负载能力要比HTTP的低很多,何况订票又不是什么机密的数据。 总会有人跳脚出来说订票啊多机密,我总是很反对,哪门机密了,车次还是余票数据?
这个HTTPS带来了很大的麻烦。
不知道哪个版本Chrome引入的安全机制,对于一个HTTPS网站,其所有引用的资源(Script和StyleSheet之类的),也必须位于HTTPS的服务器上,否则拒绝执行。而我并没有HTTPS服务器,因此,Chrome下自动更新华丽地挂了。 然后是Firefox。Firefox下播放不了音乐,我一直以为是Firefox不支持,后来才发现是Firefox的安全机制在作怪:HTTPS的网页拒绝播放来自于HTTP的多媒体文件。 这俩奇葩让我伤透了脑筋。然后无意中瞥见GitHub竟然是HTTPS的,So…… 转移过去,变成了顺理成章的事情,我求爹爹告奶奶没求来一台HTTPS的服务器,虽说有免费的SSL证书什么的但是我去申请的时候,连那提供商的网站自己都证书错误了。
于是事情都解决。
而第二个问题,GitHub的负载能力为什么这么弱,原因在于GitHub根本不适合作为CDN服务。著名博客比特客栈的文艺复兴,对此做了详细解释:
- 它并非静态文件服务器,换句话说,所有请求访问都要先经过一堆服务器代码处理,降低了它的响应速度。
- 它返回的MIME与文件无关(永远是text/plain),某些浏览器,例如说IE,不会执行MIME类型错误的javascript文件。
- 它返回的Cache-Control Header不允许浏览器缓存文件,等于失去了CDN最基本的功能。 恰恰因为12306订票助手不运行于IE,也不希望更新文件被缓存,Raw file的后两个劣势才没有显现出来。但剩下的那个劣势,却让Github的响应速度大打折扣,不得不暂时封锁Raw file访问。
针对这个问题,原文作者直中要害的提供了两个层面的解决方案:
- 使用GitHub作为CDN的正确之道:
那么,Github作为CDN的正道是什么?Github Pages。通过加入gh-pages branch,你可以修改和发布自己repo的文件。值得提醒,Pages虽然免费,并非资源无限,详见官方Disk Quota的描述——“虽然我们没设上限,但请各位合理使用。”
Github轻描淡写的说合理使用,而不是严明规章到MB、GB,其实是一种潜意识的相互信任。这是一种在贫富悬殊供求关系紧张的中国日益缺少的东西,12306订票助手的存在就是一种印证:乘客不相信12306,12306不相信乘客,最后逼出一个12306订票助手,每天乃至每半天更新一次来满足中国人订票回家的需求。
- HTTPS下如何引用HTTP资源:
请问Google Reader,是怎么在HTTPS域下播放优酷与土豆等非HTTPS的视频?我们在去年9月发现了同样的问题,Google自己是这样解决的:“Chrome 21之后,在SSL加密页面embed非SSL的Flash会怎样呢?会被默默的屏蔽掉,只留下一句console报告。那Google Reader是怎么绕过这个问题看优酷与土豆视频的?他们iframe了一个非SSL页面,再在里面引用flash(引用页连域名都是不同的)”
同理也适用于Javascript,这也是12306订票助手当前的解决办法(Firefox除外)。不再需要SSL下的CDN了。
订票助手的作者木鱼,不堪忍受各界观光团纷纷造访他本开源在GitHub上的订票助手代码仓库,最终删除了项目。但他表示仍将继续精简/改进这款订票插件。
因为这个插件,铁道部甚至投诉至工信部,要求其责令各家浏览器提供商停止提供附带抢票功能的浏览器的下载。不过就本文发表前,各家浏览器厂商均表示尚未接到相关通知。
铁道部为了保证“公平”,他们开始采取技术手段,针对使用插件的浏览器采取反制措施,其结果如何,目前看来,恐怕不能令他们和他们的上峰满意。
网友码农1999在新浪微吧上发布文章《傻大黑粗+殃及无辜:12306技术反制猎豹浏览器代码级分析》,列出了12306.cn的具体反制措施,其中主要有四种手段。
手段一: 频繁修改具体功能函数名称,让抢票插件调用失效。
这是12306开始技术反制时最常用的小技俩。码农都知道,这种“小修小补”的技术屏蔽手段,只要针对12306修改的具体功能函数做修改,即可实现插件正常使用。整个破解及插件更新时间不超过1小时。
手段二:1月20日开始屏蔽浏览器user agent
1月20日进入春运购票最高峰(可订2月8日车票),12306使出了屏蔽浏览器user agent的手段,如此一部分没有用抢票版的用户也被屏蔽,一些用户反应未用插件却登陆12306时白屏,进入不到网站。
针对屏蔽 user agent,只要修改浏览器的用户代理即可实现登陆12306。
手段三:限制连续2个操作的时间间隔,所有浏览器在未使用抢票插件情况下或无辜中枪。
如在提交订单时12306判定输入验证码及提交的时间间隔短,即使验证码输入正确,亦会被12306弹出“验证码错误”。此种屏蔽手段造成的后果是:1、抢票插件自动提交订单失效;2、无论使用哪种浏览器的用户,无论使不使用抢票插件,只要“被判定”时间间隔短,即提交订单失败…破解此屏蔽手段,甚至不需要修改插件代码,只需取消抢票插件的“自动提交”功能,手动输入验证码即可。
手段四:12306后台增加一些逻辑判断,会踢出用插件用户的登录状态。
这些逻辑判断包括:
限定操作时间间隔、提交订单时间间隔、查询刷新间隔等。
这些手段均不能保证只屏蔽抢票插件用户,均有可能让无辜的用户,被12306判定为“插件用户”,不能正常登陆,买不到车票。
对于这些反制措施,作者认为:
- 12306用的那些技术反制手段真心很糙,很临时工。一个词形容:傻大黑粗。
- 12306这些小花招,在浏览器厂商面前,效果不大。
- 12306的反制措施还带来更大的网站崩溃可能性,殃及无辜。
文末,作者给12306提出4句话:
- 每一个登陆12306的用户,都有权利选择使用的浏览器及正当手段提升使用体验,屏蔽只会加剧无谓的劳动量。
- 请不要再聘用实习生或者临时工进行屏蔽抢票插件,请尊重程序猿的智商。
- 12306对“无辜”被屏蔽的用户造成极大的不公平。
- 12306作为投资5亿的网站,请亮出你技术屏蔽的“杀手锏”。
在微博评论中,Super_Wang指出:
用技术手段屏蔽标准http请求。。。无语,只要它没离开http,找出规律也就是个时间问题。对关键请求加单次有效的短信延时二次认证应该是个不错的办法,客户体验就难说了
执信飘飘想听听其他人的看法:
大量游戏外挂都不能得到有效解决,何况这是一个甚至没有做验证码适配的脚本程序而已,个人觉得这的确很难做处理。因为不具有很明显的特征性,很难判断。
路过看一下!
我来留下脚印
太厉害啦!值得我们学习
秒赞不是偶然,是一种态度!