不管你是遇到加小尾巴跳转,iframe 嵌套广告,302 跳转,还是 JavaScript 脚本劫持.
只要是基于旁路设备监听抢答数据包这个原理的劫持行为.
这套 iptables 规则就能应对.
注意:目前仍在实验阶段,浙江移动测试有效,无法保证不会对正常的连接产生破坏.
主要原理:基于 IP 头 TTL 值的判断丢包.并使用 ACK 空应答包,和装满数据的 TCP 包来更新 TTL,防止正常 TTL 变动导致连接断开.
需要模块
bpf
u32
connmark
mark
注意
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 也正常) |