原文发布于 我的博客,刚刚经历了一次数据丢失和迁移,正在慢慢找回以前的文章。希望和大佬们换个友链~
与移动的缓存问题进行斗争要追溯到两年前,那时候因为移动竟然连 cnpm 的数据都进行缓存。并且令人喷饭的是:移动的缓存服务器不但经常速度慢到堪比万年王八跑马拉松,甚至还经常宕机,导致我只想安安静静的写个代码却不得不面对一片鲜红的报错:
就此事我也不止一次的投诉到移动的客服部门并且要求至少将我这个宽带的账号加到所谓“白名单”中。当时还写过有理有据的投诉邮件:
但是不知道是福建移动的客服和技术部门是临时工还是其他什么原因,在承诺会解决问题后也一直没有改善。不得已,只能暂时用比较蠢的办法去解决这个问题:使用路由器上的 iptables 判断数据包的内容,如果数据包内包含已知的移动缓存服务器地址(范围)就丢弃这个包:
iptables -I FORWARD -m string --string "Location: http://211.143.146." --algo bm -j DROP
这个方法有效,但是移动的缓存服务器是无穷无尽的,每次都去添加规则真的让人头大。而且这样进行文本的对比太占用资源可能会造成网速下降。后来不得已换了其他运营商的宽带,也就慢慢忘了这茬。
但是最近因为搬家后重新用上了移动的宽带(无奈之举,小区只有移动的口),又要开始面对移动无穷无尽的缓存黑洞:下载些东西总会被移动友好的劫持,并且慷慨的用小水管般的下载速度回馈广大新老用户。
无奈之下只能重新想办法对付令人作藕的移动缓存。
重新打开许久没用的 Wireshark,选定一个确定会被劫持到缓存服务器的地址,抓包分析一下劫持的经过:
可以看到我们对源站发起 GET 请求之后,源站返回了一个 302 跳转的包。显然这个 302 跳转包是移动伪造的劫持包。那应该就这个劫持包来分析一下特征并将其丢弃应该就可以对移动的缓存说 886 了。
分析了几个移动返回的 302 劫持包后,发现一个特征:这些包的 TTL 都比较小,范围是 20-30 之间。正常的服务器给的包应该没这么低(吧)。
继续使用路由器的 iptables,根据这个特征,写一个 iptables 规则来丢弃这些劫持包:
iptables -I FORWARD -p tcp -m tcp -m ttl --ttl-gt 20 -m ttl --ttl-lt 30 -j DROP
这样是不是就完美了呢!不,考虑到可能还真的有其他幺蛾子服务器发来的真实数据包的 TTL 也在 20-30 的区间范围内,应该再加一层判断。对比了移动的 302 劫持包和正常的 302 跳转包的报文后,发现移动的劫持包的状态位包含 FIN, PSH, ACK 而正常的 302 跳转包一般不会这三个都有:
移动的劫持包 ↓
正常的 302 包 ↓
(同时可以看到正常 302 包的 TTL 都没这么低)
那么就在 iptables 规则里加上状态位是否包含 FIN, PSH, ACK 的判断:
iptables -I FORWARD -p tcp -m tcp -m ttl --ttl-gt 20 -m ttl --ttl-lt 30 --tcp-flags ALL FIN,PSH,ACK -j DROP
这样应该就能在丢弃移动劫持包的同时尽可能减少误伤正常数据包的可能。
访问一下刚才确定会被劫持的地址:
Bravo! 看起来移动的劫持包已经被路由器的 iptables 丢弃了,所以可以下载源站的内容了。
这个方法不一定对所有地区的运营商劫持都有效果,主要还是靠分析一下运营商劫持包的特征加以判断再写成 iptables 规则进行丢弃,有需要的同学可以自己试一下。
上述方法只能针对运营商使用旁路设备对访问源站的请求进行抢答的劫持情况(抢答发送 302 跳转包劫持到缓存服务器),对 DNS 劫持无效。
旁路设备劫持的某些情况:下载文件跳转到缓存服务器、购物网站跳返利、页面 js 被加💩等。
以下引用自 运营商劫持 一文,原文作者 李涛军
DNS 作为互联网的基础设施之一,起到把域名转换成 IP 地址的作用,比如 www.baidu.com --> 115.239.211.112 。 各大运营商通常会以省为单位建设 2-4 台递归(或缓存)DNS 给用户使用,在 PPPoE 拨号时自动配置。 假若用户输错了域名,正常情况下 DNS 服务器会返回 NXDOMAIN(nonexistent domain)错误,然后浏览器或应用程序会报「域名无法解析」错误 运营商通常会对 NXDOMAIN 结果进行污染,返回一个假冒的 IP 地址,这个 IP 地址指向运营商的服务器,于是你便看到了「贴心」的满屏广告的各种网址纠错页。 这种方式简单粗暴,用户一般也不会太反感,而且似乎也不会违反任何法律法规
用户跨运营商访问网络时,运营商可能需要为用户支付网间结算费用。比如中国移动宽带用户访问位于中国电信网络的服务器,中国移动必须为这些流量或带宽支付给中国电信网间结算费用 由于众所周知的原因,网间结算费用十分昂贵,为了节省网间互联费用,部分运营商部署了缓存服务器,在用户跨网访问时,采用技术手段将用户与目标服务器的连接劫持到自家的缓存服务器上
1
ScotGu 2019-10-07 06:17:11 +08:00
大佬就是大佬,自己动手,丰衣足食。
话说这些缓存服务器还可以收集起来搞事情。 |
2
qiufeng812 2019-10-07 06:37:12 +08:00
用 adguard home,一次搞定
|
3
SilencerL OP @qiufeng812
AdGuard Home 可以干掉移动的 302 劫持吗,我稍微看了下好像只能解决 DNS 劫持…… |
6
wgq2633 2019-10-07 08:05:48 +08:00 via Android
膜拜大佬
|
7
pypy 2019-10-07 08:33:16 +08:00
你这种方法有一定的门槛,且不通用。通用场景下可以依次做下面的配置:
1. 更换 DNS 为非运营商默认;建议配置加密 DNS。关键字:dnscrypt,DoH,DoT ; 2. 浏览器开启 HSTS 功能。如果浏览器不支持,可以通过插件实现。关键字:HSTS preload ; 以上两步可以解决大多数问题,如果想完全规避,采用第 3 步: 3. 全局或指定 URL 走 proxy。proxy 工具选择“科学类”的。 |
8
wwqgtxx 2019-10-07 08:51:40 +08:00 2
@pypy
首先,很多移动网络直接无脑劫持 HTTP,根本就不在 DNS 上动手脚。 其次,很多下载链接并不支持 HTTPS 所以 HSTS 无解 第三,移动对国内的很多文件也进行垃圾缓存,所以选择代理只会使速度变得更慢 |
9
SilencerL OP @pypy
第一个情况:更换 DNS 没法解决这种运营商针对热点资源下载的旁路设备抢答劫持(根据 URL 和文件名之类的劫持) 第二个情况:旁路设备抢答劫持通常针对 http 连接,开 HSTS 也救不了没配置 https 的网站…… 第三种情况:曾经用过,使用国内的服务器挂个 $$ 去规避劫持,但是自己服务器的带宽又基本都是 10M 以下的,浪费了宽带 200M 的速度,国外服务器同理,跑不满带宽。 所以出于无奈才只能用 iptables 去做反劫持的事。 |
10
pypy 2019-10-07 09:14:55 +08:00
|
12
wwbfred 2019-10-07 09:19:00 +08:00
为了省事把 FIN 一起扔过来结果反而被用来过滤,移动还真是搞笑.
另外建议使用真宽带,联通电信最近这种事情基本上不多了... |
13
wwbfred 2019-10-07 09:21:42 +08:00
最好再在 OUTPUT 链里也加上,这样路由器上的服务也不会被劫持了.
|
14
wwbfred 2019-10-07 09:25:06 +08:00
说错了应该扔到 PREROUTING 里...
|
15
0ZXYDDu796nVCFxq 2019-10-07 09:44:27 +08:00 via Android
给这些缓存投毒试试
自己建个 http 服务器,放个非法内容,下载,如果被缓存,去网监投诉 |
16
leafleave 2019-10-07 10:10:56 +08:00 via iPhone
@SilencerL 听说移动的连接 cloudflare 效果很好,你可以试试用国外的服务器使用 v2 套上 cf 加速
|
17
shanlan 2019-10-07 11:04:49 +08:00
其实楼主,真的是热门资源的话百度云等网盘的离线下载绝对比你源地址下载要快(被百度云限速除外)
|
18
SilencerL OP @shanlan
😂 所以应该如何正确使用百度云的离线下载功能进行 cnpm i 的操作以规避 npm 淘宝源数据被劫持的问题,百度云只能用来解决下载一些 [狭义上] 的热点资源(比如软件安装包、电影等),而有一些需要鉴权下载或类似 npm 这样是属于软件内集成下载功能的操作就无能为力了。 所以本文所述的方法是针对劫持的根源进行解决~ |
19
huaxie1988 2019-10-07 12:10:14 +08:00
你的规则可能存在误伤,观察下你们那边 IPID 是不是固定的,我们这边 IPID 固定的,所以我用了 IPID 和内容 2 方面判断,使用的 u32 模块,规则是
iptables -A forwarding_rule -p tcp -m u32 --u32 "2&0xFFFF=0XF2 && 0>>22&0x3C@ 12>>26&0x3C@ 9=0X33303220" -j DROP |
20
xiaoke 2019-10-07 12:46:06 +08:00
膜拜技术流!
|
21
dusu 2019-10-07 13:01:26 +08:00 via iPhone
提供解决方案参考
对于重要的下载地址直接 rewrite aaa.rar 可以重写为 aaa20191007.rar 根据更新频率自己安排时间颗粒度 保证用户下载的内容是最新的就行 |
22
qiufeng812 2019-10-07 13:46:32 +08:00
@SilencerL 我这里三家大厂的 dns。都被移动封了 53 端口。所以,无论设置什么 ip。都会被移动的 dns 机组抢答,而且我直接没有正确的 dns 给我应答。你不如先查查,你用的 dns 有没有被移动封了 53 端口。
你如果第一关的 dns 会应答正确的 ip。就继续 iptables。 我现在看视频的效果比原来移动的抢答状态下爽。说明,我应该没被移动 http 劫持。 httpt 劫持要比 dns 劫持来得花钱,能 dns 搞定的,自然不需要更花钱的 http 劫持。 |
23
celeron533 2019-10-07 13:56:17 +08:00 via Android
尝试在 URL 后面加废参数能不能强刷缓存呢?比如 http://foo.bar/download.zip?dummy=123
|
24
SilencerL OP |
25
eason1874 2019-10-07 16:47:39 +08:00
确实,两三年前我也投诉过这个问题,缓存就算了,缓存服务器还经常宕机,导致的问题不是慢,而是根本访问不了。
不过这两年 HTTPS 基本普及了,就很少遇到这个问题了。 HTTPS 是不会进行 HTTP 302 调度的,你以后用 HTTPS 的就行了。如果 HTTPS 也被 302 了,那不关运营商的事,那是网站本身 CDN 启用了这个调度服务,像又拍云就有提供 HTTP 302 调度。 |
26
SilencerL OP @celeron533
😂不行,我曾经也很天真的试过…… |
27
SilencerL OP @eason1874
是的,https 完全可以解决这个问题。 但是引用 https://www.v2ex.com/t/313702 中的一句话: “其实这就像很多 Linux 发行版的仓库一样,包本身有单独的 GPG 签名来防篡改,因此文件本身可以通过 HTTP 传输,也可以被代理和缓存。” 还有很多地方没上 https,这就很让人头大……不过 https 是大势所趋,运营商 http 劫持的问题终归会被解决掉(吧)。 |
28
linchao1900 2019-10-07 17:02:08 +08:00
iptables 反运营商劫持,已用 2 年。
#ISP 防劫持 #误伤极大 #iptables-mod-ipopt iptables-mod-conntrack-extra iptables-mod-filter iptables -I FORWARD -p tcp --sport 80 -m ttl --ttl 65 -j REJECT iptables -I FORWARD -p tcp --sport 80 -m ttl --ttl 65 -j LOG --log-prefix "ISP:" CDN 劫持 也很多。比如导航站,基本劫持。 #Hao123 防劫持 iptables -I FORWARD -p tcp --sport 80 -m string --string "var u='http://',u='https://www.hao123.com/?tn=" --algo bm -j DROP |
29
huson 2019-10-07 19:52:10 +08:00
windows 有没有办法
|
30
SilencerL OP @huson
我查阅了一下 Windows 下的 netsh 命令参数,好像没有可以实现类似功能(根据 TTL 和 Flags 来写策略)的方法…… 所以如果可能的话换一个支持 iptables 的路由器吧还是。 |
31
Unclev21x 2019-10-07 21:30:17 +08:00 via iPhone
给大佬鞠躬!🐂!
|
32
CloudnuY 2019-10-07 23:29:03 +08:00
投诉过几年联通没起作用
也用了几年在路由器用 iptables 拦截特征包防劫持了😂 |
33
ungrown 2019-10-08 11:54:46 +08:00
楼主,我挺好奇你平时都是上什么网站下什么资源的,因为我自己是真的很久没下到过 HTTP 的资源了(除极少数古老小众站点)。
不管是软件、文献、多媒体、老少咸宜的亦或是 XX 禁的,不管是境内境外站点上的,我真的很久没碰上 http 的了。 |
35
dawnh 2019-10-08 16:22:56 +08:00
这么多年了,原来移动还没解决这个缓存服务器经常挂的问题啊。
另外,不要以为有了 HTTPS 就万无一失了,移动的缓存可是有连 SSL 都给你 proxy 的行为的,而且它的缓存服务器也经常炸,表现在 HTTPS 上就是证书拿不到。 |
36
wwbfred 2019-10-08 17:37:01 +08:00
@linchao1900 你这个误伤大倒是次要的,每个 http 包都要遍历查找一遍...
|
37
fhbyljj 2019-10-13 10:57:05 +08:00 via Android
大佬,收小弟吗
|
38
barnettluo1994 2019-10-15 20:45:24 +08:00
找个电信或者联通的朋友给你做隧道吧,你隧道过去就行····别直接用移动的就行
|
39
barnettluo1994 2019-10-15 20:48:05 +08:00
你可以走我这里的一个交换中心变成电信或者联通的 ip 用。还行
|
40
a154415433 2020-01-26 10:27:42 +08:00
被移动强*了 2 年了,谢谢分享,等等试试,请问,路由用的是 merlin,还是 openwrt
|
41
SilencerL OP @a154415433
用的是梅林, 理论上所有支援 iptables 的路由器都可以用这个方法 |
42
a154415433 2020-01-29 20:28:24 +08:00 via Android
@SilencerL 我也用的梅林,这个输入上去无法找到 ttl
|
43
imyoona 2020-02-01 17:14:34 +08:00
0594 测试了一下。现在这个地址劫持返回了个北京移动的 cache。这个靠 ttl 的规则可以过滤福建移动,对北京移动就没办法了,而且我这里的 302 包没有 FIN, PSH, ACK
|
44
SilencerL OP @imyoona
举一反三一下观察劫持包的特征吧…… 实在不行就只能靠屏蔽 IP 段来解决了。 |
45
a154415433 2020-02-02 10:52:59 +08:00
admin@RT-AC66U-F768:/tmp/home/root# iptables -I FORWARD -p tcp -m tcp -m ttl --t
tl-gt 20 -m ttl --ttl-lt 30 --tcp-flags ALL FIN,PSH,ACK -j DROP iptables v1.3.8: Couldn't load match `ttl':File not found |
46
a154415433 2020-02-03 18:11:59 +08:00
@SilencerL 用这个命令成功感谢,
iptables -I FORWARD -m string --string "Location: http://117.143.109." --algo bm -j DROP |
47
a154415433 2020-02-03 20:07:54 +08:00
iptables-save 保存不了,小白折腾不动了,
|
48
OllyDebug 2020-03-22 08:33:46 +08:00 via iPhone
为啥不用 https
|