歪歪猪作坊 编程是一门手艺

中国电信“网络尖兵”的初步研究

2009-11-13

广州的中国电信也跟随其他地方的步伐,开始设施检测多部电脑用一条ADSL线上网的措施。发现有多部上网时,就会在某一部电脑上的浏览器弹出一个页面,说发现多部电脑上网,请联系电信之类的话。据说是按增加多少部电脑收多少费用这样来实行的。随着上网本的普及,一个家庭有多部电脑很普遍,看来电信的野心不小。

经过一天的观察,初步研究了一下它的原理和行为。

首先,原理是什么呢?多部电脑用同一条ADSL线上网,一般都使用了NAT(Network Address Translation)技术,把所有内网发出去的IP包都进行了地址转换,再发到互联网上,内网IP,MAC地址这些信息是绝对不会透露到外网去的,网上有一个很流行的破解“网络尖兵”的帖子,说把内网的所有机器的MAC地址都改成同一个,这个是不对的,而且会造成内网的通讯障碍的。那么怎么知道NAT后面有多少部机器在共享上网呢?原来NAT虽然进行了地址转换,但是有一些IP包的信息基本保留了下来,其中最重要的一个是IP包里面的IPid这个域,这个域原来的作用是在IP包太大,给拆成多个部分传输(Fragmentation)时,可以在目标地正确地组包,也就是说,只要保证它在较短的时间内不重复就可以了。但是,大部分的操作系统的实现,这个域是自增长的,也就是说从开机之后,开始发第一个包开始,每发一个包就加一。由于目前大部分的NAT并没有处理这个域,所以如果在公网对ADSL发出的IP包进行观察,如果内网只有一部机器时,看到的IPid的域就是一个不断增长的序列,如果有两部机器,除非两部机器刚好同时开机和同时向外发包,否则从外网观察,就会看到两个不同范围的增长的序列,如果以时间作为横轴,Ipid作为纵轴,可以看到有两条增长的直线。所以只要在局端对IP包根据IPid进行简单的统计分类,就可以大致地看出一条ADSL后面有多少部机器了。

电信大概就是靠这个还有其他一些措施组合起来判断ADSL后面的机器数量了。那么发现超过数量后,电信会怎样处理呢?经过观察,大致是这样的:规定数量以内的机器不作干扰,数量以外的机器在一定的时间内,所有TCP连接都直接发Reset中断,除了到80端口的TCP连接,如果发现是HTTP请求,就直接返回一个302的跳转的应答,跳转到电信展示的警告页面,所以用户就看到了警告的页面,而且由于其他的TCP链接都给中断了,所以感觉发上网中断了。UDP连接不受影响,所以QQ和域名解析都不受影响。

由于IPid可以用来检测内网的主机数量,而且可以用这个来更准确地追踪主机的上网行为,在国外,很早就有针对这个的解决方法,但是注意,他们的着重点是安全,不是象我们一样,对付运营商。所以他们的做法是对IPid进行随机取值,而且用一个算法保证在短时间内,这个值不会重复。BSD系统(应该包括Mac OS X)有一个Kernel的参数:net.inet.ip.random_id,把它设为1,就可以使IPid的值是随机的。使用OpenBSD的Packet Filter做NAT,它也有一个叫Traffic Normalization的功能,可以使出去的IPid随机化,这样外网就无从检测到内网有多少部机器了。但是那这个方法对付电信会适得其反,因为电信采用了宁可杀错,不可放过的策略,电信的系统希望看到的是规定数量以内的IPid的有序的序列,一旦发现大量随机序列,估计就给判断成内网有大量的机器,这是会发现网内的机器可以上网的几乎没有了,要不就是干脆上不了网,要不就是会弹出警告窗口。

所以,要对付电信的话,一定要让出到外网的Ipid序列化,最好只有一个序列,还好国内已经有人做出来了,一个是Linux的iptables的修改:http://www.chinaunix.net/jh/4/909127.htmlhttp://linux.chinaunix.net/bbs/viewthread.php?tid=909127

根据这个修改,用Linksys’ WRT54G/GL/GS, Buffalo WHR-G54S/WHR-HP-G54 或者相同解决方案的路由器的Image也有人做了出来,是基于Tomato的修改:  http://www.right.com.cn/forum/viewthread.php?tid=13909http://www.high3.cn/view.asp?webid=214

我自己没有试过,有遇到相同情况的可以去试试。因为之前有人反映HTTP代理也不行,目前我的解决方案是Socks5的代理,好像还没发现什么问题。

参考资料:

 

A Technique for Counting NATted Hosts


上一篇

评论

内容