解决校内网HTTP劫持的问题

今天在用apt安装一个软件的时候,出现了奇怪的错误:

Get:1 http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin xenial/main amd64 libgnomecanvas2-0 amd64 2.30.3-2 [82.7 kB]
Err:1 http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin xenial/main amd64 libgnomecanvas2-0 amd64 2.30.3-2
  Writing more data than expected (82993 > 82720)
E: Failed to fetch http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin/pool/main/libg/libgnomecanvas/libgnomecanvas2-0_2.30.3-2_amd64.deb  Writing more data than expected (82993 > 82720)

E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

后来在网上查找资料,联系之前校园网的通知,想到了校园网采用了文件缓存。。。

中国的网络是奇葩的,原因之一是有奇葩的屌丝运营商。

许多小运营商(二级运营商、三级运营商、N级运营商)为了节省成本,会使用缓存系统。 这个缓存系统可以认为是一种CDN,如果做得好的话,不仅会节省成本,也会提高用户体验, 例如许多小区里大家看优酷视频从来不会缓冲,下载速度都有3MB/s以上的速度。 然而,这些缓存系统并不是CDN,而是一种非常没有节操的黑盒子。

  • 你不知道什么请求会被缓存,没法控制。
  • 你不知道会被缓存多久。
  • 这种缓存不遵守任何行业内的规则(例如不遵守Cache-Control头)。
  • 发现缓存了错误的内容,你没有地方投诉。

其劫持的手段也是非常的无节操的,主要受益于郭嘉的某墙开发的成果。其劫持原理大致如下:

  • 客户端C向服务器S发出一个HTTP请求;
  • 运营商网关将该请求分光(复制)送到缓存服务器;
  • 缓存服务器如果发现命中缓存,则伪装成S返回一个302响应,该响应通常比S的正确响应早到,因此C接受 了该响应,而忽略了S的响应,从而跳转到缓存服务器取数据;

是的,这正是伟大的墙发送RST的方法。

After this operation, 508 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin xenial/main amd64 libgnomecanvas2-0 amd64 2.30.3-2 [82.7 kB]
Err:1 http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin xenial/main amd64 libgnomecanvas2-0 amd64 2.30.3-2
  Writing more data than expected (82993 > 82720)
E: Failed to fetch http://202.204.48.68/files/50420000001D8F93/cdn.packages.deepin.com/deepin/pool/main/libg/libgnomecanvas/libgnomecanvas2-0_2.30.3-2_amd64.deb  Writing more data than expected (82993 > 82720)

E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

显然我用apt更新的时候,某一个依赖文件被劫持到了202.204.48.68….

解决办法:

通常缓存服务器的IP是有限的,因此我们可以这样绕过运营商的劫持,在或自己机器上添加一条iptables规则:

sudo iptables -A INPUT -p tcp --sport 80 -m string --string "Location: http://202.204.48.68" --algo bm -j DROP

如果是网关,则将INPUT替换成OUTPUT

该规则的意义是,如果某个HTTP响应包(这里并没有真正判断是否HTTP,仅分析来自80端口的包)中含有 Location: http://202.204.48.68 字样,就直接丢弃。这样后续S真实的响应包就能被客户端接收,从而保证正确的通信。

这里我们要感谢该运营商没有像某墙那样的没节操,某墙在向C发送RST的同时,也向S发送了RST,而该缓存服务器并没有 向S发送RST,彻底破坏tcp通信。


文章作者: crazyX
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 crazyX !
评论
 上一篇
Python & Mysql Python & Mysql
为了准备GPLT比赛,需要自己拼凑散题和练真题,散题的话,直接vjudge就好,真题的话,需要到源oj上去,不方便以比赛形式练习,自己开发的oj功能也不够完善,时间紧迫,经过和队长smile的商讨,最后决定采用爬虫+hustoj的形式解决需
2017-03-05
下一篇 
代码查重工具sim 代码查重工具sim
在瞎搜东西的时候,发现了一个大牛的博客 看起来很厉害的样子。。。做了一个LaTeX的语法检查并给出适当的提示,上wiki上一查发现他竟然是CVS第一个版本的发明者和开发者。。。Dick grune这是他开发的程序 = = 当然,也发现了一个
2017-01-21
  目录