不管你是遇到加小尾巴跳转,iframe 嵌套广告,302 跳转,还是 JavaScript 脚本劫持.
只要是基于旁路设备监听抢答数据包这个原理的劫持行为.
这套 iptables 规则就能应对.
注意:目前仍在实验阶段,浙江移动测试有效,无法保证不会对正常的连接产生破坏.
主要原理:基于 IP 头 TTL 值的判断丢包.并使用 ACK 空应答包,和装满数据的 TCP 包来更新 TTL,防止正常 TTL 变动导致连接断开.
需要模块
bpfu32connmarkmark注意
connmark的标志位需要 0x7FF 长度来记录 MSS 值,还有 0xFF 来记录 TTL 值.默认记录位置为 0x07FF00FF.mark的标志位需要 0x1 长度.默认记录位置为 0x00000001.工作原理
SYN+ACK包的 TTL 值和 MSS 协商值.ACK|ACK&&PSH,且 TCP Data 长度为 0 或长度为 MSS 协商值的包对保存的 TTL 值更新. 1
nfroot 2017-01-23 00:10:48 +08:00
之前看劫持包的 TTL 都不对的时候 就在想这个问题了 只是对这个太不了解…… 自己技能也达不到这个级别……
点赞 |
2
RobertYang 2017-01-23 00:22:23 +08:00 via Android
点赞,被电信插广告他们还不认
|
3
lslqtz 2017-01-23 05:00:57 +08:00
如果旁路设备知道客户端与它的 TTL ,那么旁路设备再检测服务器 TTL 加起来的话。
|
4
est 2017-01-23 09:24:27 +08:00
crazy idea 。。。居然能在 iptables 做这么多事。。。学习了。
|
5
est 2017-01-23 09:27:30 +08:00
结合 ip netns 可以只对浏览器生效。这样可以限制误伤范围。
|
6
TMily 2017-01-23 10:30:04 +08:00
额 能不能将特定 WAN 口改为特定防火墙区域呢,多拨的话,都不一定是哪个口拨上的说
|
7
KCheshireCat OP |
8
KCheshireCat OP |
9
est 2017-01-23 11:27:03 +08:00
@KCheshireCat 能不能用 bytecode 实现服务器主动发一条 TTL 到达不了客户端的 ACK,PSH 但是墙能收到。。。然后 seq 号是不是就混乱了呢?
|
10
est 2017-01-23 11:28:09 +08:00
@KCheshireCat 你们二次元头像党又是玩技术的太可怕了。
|
11
aru 2017-01-23 13:45:52 +08:00
1. 能否限制只对 tcp port 80 起作用(也许能降低 cpu 占用率?)
2. openwrt 下有没有朋友来搞搞? |
12
feng32 2017-01-23 20:04:07 +08:00
好东西,等晚上回去在 openwrt 上测试一下,依赖的模块是否都现成的看一下
|
13
KCheshireCat OP @est iptables 本职工作是防火墙啊,要发包大概要打补丁实现了吧,这方面我不太懂
|
14
KCheshireCat OP @aru 我用 x86 的 AMD 速龙 x4 老爷机跑满 100M 是一点问题也没有,几乎没有负载,轻轻松.
路由器的嵌入式平台就不知道了,只对 80 起效是可以做到的,但是上网主要流量也就是 80 的多啊... |
15
aru 2017-01-23 23:19:20 +08:00
@KCheshireCat
p2p 下载基本都是非 80 的,而且流量很大。我的大流量应用就是 PT ,经常达到 200Mbps ,估计加上这个会是一个瓶颈。 今天尝试在 lede ( openwrt fork )上添加项目的 iptables ,找不到 bpf 模块 :( |
16
KCheshireCat OP @aru
你需要针对端口限制的话可以在要填"{your WAN}"的那两行加入端口匹配条件. 然后一般来说容易缺失的 iptables 模块就是 u32 或者 bpf 了,大多数人只是用 iptables 解决些简单的需求,所以不会用到这种需要写字节码的模块. 不过可以自己编译 openwrt 固件的时候把这几个模块一起编译进去,再或者你可以看看 openwrt 官方源有没有提供补全 iptables 的包,这样就不用自己编译了. |
17
aru 2017-01-24 00:03:18 +08:00
@KCheshireCat u32 我编译和加载了, bpf 实在没找到配置选项,网上找了挺多地方,没发现究竟是哪个配置参数
|
18
JJaicmkmy 2017-01-25 20:57:22 +08:00
@KCheshireCat 如果是自己的服务器的话,可以在服务器上也 DROP 掉 RST 的包,对 SS 有奇效。
|
19
KCheshireCat OP @JJaicmkmy #18
这么弄的话好像会触发路由黑洞,以前看别人提过。 |
20
Siril 2017-02-06 14:34:52 +08:00
awesome idea , but.....
看 issue ,疑似有误伤,求解惑。 不知可否在其他发行版复现这个问题 |
21
KCheshireCat OP |
22
Siril 2017-02-06 15:42:17 +08:00
@KCheshireCat 但愿能找到改进措施。
---------- 下面是脑洞: 仔细考虑后,即使利用 libnetfilter_queue 做出一个,抛开稳定性、吞吐量不谈, 我感觉按延迟也不靠谱, ack 的时间受目标服务器负载的影响,不能说明问题; 主动学习数据包长度、 ttl 值 也难免误伤, 恐怕还要解析数据包内容 一般也就是内容有固定特征的 302 redirect 、 meta-refresh 、 javascript 啥的。 字符串黑名单过滤之。 思路有了,项目起名叫 WFG 不错。 XD |
23
KCheshireCat OP @Siril #22
最早最早的时候我也是用 string 模块过滤字段的,但这么作通用性太差,自己用还不错,写作项目的话以后维护起来会变成又臭又长的规则表,而且对单个用户来说有用的可能就其中的几个。某条规则什么的时候已经失效也没法验证。 最重要的是运营商改劫持模板方便,我们验证规则,抓包困难。这样十分吃力。 |
24
Siril 2017-02-06 16:30:23 +08:00
|
25
Siril 2017-02-06 16:38:31 +08:00
啊不能改自己的回复, 突然想到如果 libnetfilter 可行, 何必玩高级花样。
既然真正的 response 在假的之后到达,那么假数据包太容易辨认了。 甚至可否将服务端返回的数据包缓存个多少毫秒超时,如果后续没有就发送这个,后续有“重复”的则 DROP 掉前一个。 --------- 可能 proxy server 更适合实现这样的功能。 |
26
akw2312 2017-02-19 03:06:25 +08:00
手邊的四川移動機器 測試有效
不過... 如果劫持是那種整個 TCP 都劫持走的目測也沒辦法了吧.. tcp traceroute 一看都被劫持走的那種 (icmp 正常, tcp 非 80 443 8080 也正常) |