irideas 发布于 05月31, 2012

运营商DNS劫持的那些事儿

上来先说一句,其实我对运营商DNS劫持了解不深,这个标题起的有点俏,还请见谅。

什么是DNS劫持

百度百科《DNS劫持》我们可以知道:“ DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。”

在百科的最后特意建立了“电信DNS劫持”一门。5月12,13日,微博上不断有关于“运营商DNS劫持”的相关微博发出及被转发评论。事实上,各地的运营商或多或少或明或暗的都会做着各种偷鸡摸狗用流量换金钱的事情。

在我前几个月去联通营业厅做宽带包年的时候,北京这里是明确了使用会“弹出广告”ADSL包年要比“不弹广告”的包年便宜一些银两。这是明面上写在协议中的“DNS劫持”弹广告的代表,这些比某些地方不吭不声的弹广告相比,我觉得还算“光明磊落”。上个周末,微博上,尤其是北京的圈中出现越来越多抱怨弹窗的声音,看来是北京这边终于开始间隙性鸡鸣狗盗了。(PS:在我之前按月付宽带费上网时,曾也不定时遇见过弹出广告的行为,所以就我看来,在运营商执行层面上对各种包年的用户,弹与不弹应没有本质区别。所以我建议大家在京包年ADSL的时候选择“弹广告”的那种。但是,但是,这真是一件让人恨恨不平的事情,但这也是国内各运营商的游戏规则,连一线的互联网企业也只能睁一眼闭一眼,有介入但不深。《百度告青岛联通流量劫持案件胜诉 获赔20万元》

微博事件1:http://weibo.com/1486697205/yj2sm4n3a

微博事件2:http://weibo.com/2573758674/yiMRc8yM5

其中微博事件2是某地运营商在360安全网址首页弹出广告,且只在该页弹出。一时使得用户以为360安全网址自己做了恶俗的浮动广告。

运营上劫持域名做了些什么

上面一直在说“弹广告”,其实劫持了域名的运营商是在做这事儿。当然一些小运营商还做了更过分的事情,这个我们稍后会提到。

360导航首页遭遇运营商劫持的一些往事

在2011年6月初,360导航做出一次重大改版之后,接二连三的爆发一些踩坑事件。其中一项是我们突然接到大量的反馈说,新版首页【不可用】,搜索选项不能切换种种现象。初步判断是业务相关的JS代码挂掉了,但原因却百思不得其解。

在之后的一次与用户远程中,抓包看了整个首页数据传输情况,突然发现了两条诡异的请求。http://hub.ad2you.com/re/re.php?src=t0033... 及 http://h.qhimg.com/js/jquery-1.6.1.min.js?tqs=20110616 第一个请求有些莫名,且全页引入jQuery时并未加任何参数,于是看到之上 http://h.qhimg.com/js/jquery-1.6.1.min.js 这个请求,响应的内容居然是:

document.write("<script language="javascript" src="http://hub.ad2you.com/re/re.php?src=t0033&t=" + encodeURIComponent(document.title)+""></script>"); 

document.write("<script language="javascript" src="http://h.qhimg.com/js/jquery-1.6.1.min.js?tqs=20110616"></script>");

显然首页的核心类库jQuery请求被调包成如上掺杂广告的形式了。由于首页所需的jQuery是在采取Load机制,运营商这么一搞jQuery晚了几个时间片,结果首页的初始化工作就功亏一溃了。全程大略如此,这样的请求被劫持是我方不能避免得(即使更改URL或增加随机数等),那我唯有做些检测机制来辅助重新初始化了。

但是。。。我们是真心不想让运营商轻易得逞。

我们是否可以斗法,如何去斗?

首先定义一下我们,我们是指在各个公司从事互联网产品服务的工程狮们。我们自然希望运营商的DNS劫持对我们产品是无效得,或者至少不干扰产品的正常使用。

至于说斗法?这是天方夜谭,作为永远从他人道路运输产品的服务商们,面对路霸的吃拿卡要我们实在没有“能力”直接对抗。即使借助法律,找衙门去告无良路霸们,也只是杯水车薪之位。所以最后的最后,我们只期待在落后一些的弹窗策略之下,可以有所变通,让广告尽量弹不出。

那么接下来说的做法写较为简单:对document.write进行包装

第一个方案是当前我所采用的简单粗暴的将document.write重写为空函数

var oldDocwrite = document.write,newDocwrite = function(str){};
if(oldDocwrite.apply){
    hao360.docWrite = function(str){
        oldDocwrite.apply(document,arguments);
    }
}else{
    hao360.docWrite = oldDocwrite;
}
document.write = newDocwrite;

显然这种方案有些太不优雅,但却也很有效。

第二个方案是豆瓣 http://www.douban.com/js/do.js 尾部用到的白名单过滤方案

// @TODO 临时应对劫持 by dexteryy


var _write = _doc.write,
_white_list = {
    "douban.com": 1,
    "douban.fm": 1,
    "google.com": 1,
    "google-analytics.com": 1,
    "googleadservices.com": 1
},
// 统计劫持情况

_hijack_stat = function(reason, env){
    var img = new Image();
    img.onload = function(){};
    img.src = "http://www.douban.com/j/except_report?kind=ra022&reason="
        + encodeURIComponent(reason)
        + "&environment=" + encodeURIComponent(env);
},

_RE_SCRIPTS = /<script.*?src=["']?([^"'s>]+)/ig,
_RE_DOMAIN = /(.+?).([^/]+).+/;
_doc.write = function(str){
    try {
        var s, safes = [], unkowns = [];
        while (s = _RE_SCRIPTS.exec(str)) {
            if (_white_list[(_RE_DOMAIN.exec(s) || [])[2]]) {
                safes.push(s);
            } else {
                unkowns.push(s);
            }
        }
        if (unkowns.length > 0) {
            _hijack_stat([unkowns[0], safes[0] || ""].join("~_~"), location.href);
        }
        try {
          _write.call(this, str);
        } catch (ex) {
          _write(str);
        }
    } catch (ex) {
        _write(str);
        _hijack_stat(ex.name + ":" + ex.message, location.href);
    }
};

以上两个方案可视项目情况而定,各有利弊。

但是如果运营商换个方案,不采取document.write,那真就要很难斗了。当然如果无耻的DNS劫持始终跟着流量入口页的对策升级方案,那咱们还是洗洗睡吧。

更过分的整站劫持

另外说一句一些地方的小运营商,如四川南充某运营商所管辖的这部分地域,直接将hao.360.cn指向自己的导航页面了,虽然样子还是定期缓存360导航的页面,但其中内容却已被改动多半。对于这些的确的用户反馈,我们只能表示无奈,且也尝试付诸于法律手段。

结语

所以结论就是运营商是用户的“最后一公里”,我们只能尽力而为也就是了。当然期待某个时刻的来临,将这一切是非之事统统扫清。

关于运营商DNS劫持的这些事,我就罗嗦至此。欢迎跟帖补充

阅读全文 »

irideas 发布于 03月04, 2012

浏览器信息探测工具

今夜做了一个浏览器嗅探工具,作用为三:

  1. 用于运营同学日常帮用户处理问题时,第一时间识别浏览器信息。
  2. 用于开发时面对常用浏览器的一些模式探测。《关于浏览器模式和文本模式困惑》
  3. 针对360的浏览器提供一些识别方案 (见源码)。

工具功能还很弱小,会视需求日后升级。

地址:http://hao.360.cn/zt/browserinfo.html

阅读全文 »

irideas 发布于 01月15, 2012

统计日志打点方案的权衡

简单的开场白:最近一段时间是经常接触前端所部署的统计代码,360导航目前所用的这款代码也是2010年某位同学写得,由于种种原因,一直想重构却始终未完成这部分工作。这篇小文简单说一下,前端发送统计日志的集中方案及其优劣。

就我所知,页面中要想发起一个http请求有如下两大阵营:

  1. DOM型选手:如利用
    上面是方案1和2的结合,当JS不被支持的时候依然可以降级为使用标签的方式(通常用于统计IP及PV了)。
    PS. 这些仅是示范代码,具体怎么用 你懂得。

    本次小文到此结束,如后续想到其他,再来补上,晚安!

    阅读全文 »

irideas 发布于 01月11, 2012

win7+chromium16因transition而导致的页面闪动

近一个月,在使用360极速浏览器 打开新标签页 ,载入360导航,当鼠标滑动一会儿后会突然发现页面有刷新迹象。这种现象约是在上月360极速版内核升级至chrome16后出现得。在忙碌完去年12月的360导航种种变化后,进入2012年的今天,终于有心思去找找这个诡异的问题了。(我本机环境是win7+360极速chromium16 其他环境未跟测)

我试图重现了这种状况,发现每次用全新的标签打开导航后,鼠标滑过顶部的皮肤选择区时,立刻会出现页面闪动。F12打开开发人员工具,在NETWORK选项卡中并未发现“刷新”带来的页面请求,可见这样的闪动不是“刷新”。这样的页面闪动像是在对页面重绘。一开始我以为是特定事件导致得,后来发现在鼠标滑过笑话前的刷新按钮时,也会出现这种现象。经过剥离DEMO测试,可以断定,是由以下css代码造成得。

阅读全文 »

irideas 发布于 12月25, 2011

png32在ie6中的透明化

关于png24与png32

PNG图片格式现在包含三种类型:
1.PNG8
2.PNG24
3.PNG32

如果你经常使用Photoshop,那你这里就会问了:到底PNG32是个什么东西。基本上PNG32就是PNG24,但是附带了全alpha通道。就是说每个像素上不仅存储了24位真色彩信息还存储了8位的alpha通道信息,就如同GIF能存储透明和不透明信息一样。当我们把图片放到不太搭配的背景上的时候,透明PNG图片的边缘会显示得更加平滑。

阅读全文 »