从原理上根绝运营商劫持,基于 TTL 的反劫持 iptables 规则 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
KCheshireCat
V2EX    宽带症候群

从原理上根绝运营商劫持,基于 TTL 的反劫持 iptables 规则

  •  
  •   KCheshireCat 2017-01-22 20:04:41 +08:00 11150 次点击
    这是一个创建于 3187 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不管你是遇到加小尾巴跳转,iframe 嵌套广告,302 跳转,还是 Javascript 脚本劫持.
    只要是基于旁路设备监听抢答数据包这个原理的劫持行为. 这套 iptables 规则就能应对.

    注意:目前仍在实验阶段,浙江移动测试有效,无法保证不会对正常的连接产生破坏.

    主要原理:基于 IP 头 TTL 值的判断丢包.并使用 ACK 空应答包,和装满数据的 TCP 包来更新 TTL,防止正常 TTL 变动导致连接断开.

    • 使用 IP 头 TTL 值是因为旁路设备不可能知道服务器和客户端之间究竟有几跳而"自己"又是在哪个位置,服务器的初始 TTL 又是多少.
    • 使用 ACK 或 ACK,PSH 标识位的空包来更新 TTL 的原因是旁路设备被没有理由发这样的包,这包不能切断连接而且本身也不携带上层数据.
    • 使用数据长度为 MSS 协商值的原因是,旁路设备要追踪 MSS 协商这个性能成本非常高,每条 TCP 连接都会协商 MSS,但不是每条连接都会触发规则需要劫持.

    项目地址

    需要模块

    • bpf
    • u32
    • connmark
    • mark

    注意

    • connmark的标志位需要 0x7FF 长度来记录 MSS 值,还有 0xFF 来记录 TTL 值.默认记录位置为 0x07FF00FF.
    • mark的标志位需要 0x1 长度.默认记录位置为 0x00000001.

    工作原理

    • 对每条 TCP 连接在握手时的SYN+ACK包的 TTL 值和 MSS 协商值.
    • 并使用 TCP flags 标志为ACK|ACK&&PSH,且 TCP Data 长度为 0 或长度为 MSS 协商值的包对保存的 TTL 值更新.
    • 其余包在不符合 TTL 值时将被 DROP.
    29 条回复    2017-08-09 20:49:52 +08:00
    nfroot
        1
    nfroot  
       2017-01-23 00:10:48 +08:00
    之前看劫持包的 TTL 都不对的时候 就在想这个问题了 只是对这个太不了解…… 自己技能也达不到这个级别……

    点赞
    RobertYang
        2
    RobertYang  
       2017-01-23 00:22:23 +08:00 via Android
    点赞,被电信插广告他们还不认
    lslqtz
        3
    lslqtz  
       2017-01-23 05:00:57 +08:00
    如果旁路设备知道客户端与它的 TTL ,那么旁路设备再检测服务器 TTL 加起来的话。
    est
        4
    est  
       2017-01-23 09:24:27 +08:00
    crazy idea 。。。居然能在 iptables 做这么多事。。。学习了。
    est
        5
    est  
       2017-01-23 09:27:30 +08:00
    结合 ip netns 可以只对浏览器生效。这样可以限制误伤范围。
    TMily
        6
    TMily  
       2017-01-23 10:30:04 +08:00
    额 能不能将特定 WAN 口改为特定防火墙区域呢,多拨的话,都不一定是哪个口拨上的说
    KChehireCat
        7
    KCheshireCat  
    OP
       2017-01-23 10:46:59 +08:00
    @est

    其实这个规则对某国家级防火墙的 RST 包也有效,只不过它会对服务器和客户端双方都发送,虽然有效但是救不了这条连接.
    KCheshireCat
        8
    KCheshireCat  
    OP
       2017-01-23 10:52:43 +08:00
    @TMily

    额,我不清楚 openwrt 上的防火墙区域是怎么回事,你可以直接填上去试试,不行的话,就用排除法.

    把不是 wan 口的接口排除掉
    est
        9
    est  
       2017-01-23 11:27:03 +08:00
    @KCheshireCat 能不能用 bytecode 实现服务器主动发一条 TTL 到达不了客户端的 ACK,PSH 但是墙能收到。。。然后 seq 号是不是就混乱了呢?
    est
        10
    est  
       2017-01-23 11:28:09 +08:00
    @KCheshireCat 你们二次元头像党又是玩技术的太可怕了。
    aru
        11
    aru  
       2017-01-23 13:45:52 +08:00
    1. 能否限制只对 tcp port 80 起作用(也许能降低 cpu 占用率?)
    2. openwrt 下有没有朋友来搞搞?
    feng32
        12
    feng32  
       2017-01-23 20:04:07 +08:00
    好东西,等晚上回去在 openwrt 上测试一下,依赖的模块是否都现成的看一下
    KCheshireCat
        13
    KCheshireCat  
    OP
       2017-01-23 21:34:00 +08:00
    @est iptables 本职工作是防火墙啊,要发包大概要打补丁实现了吧,这方面我不太懂
    KCheshireCat
        14
    KCheshireCat  
    OP
       2017-01-23 21:36:29 +08:00
    @aru 我用 x86 的 AMD 速龙 x4 老爷机跑满 100M 是一点问题也没有,几乎没有负载,轻轻松.
    路由器的嵌入式平台就不知道了,只对 80 起效是可以做到的,但是上网主要流量也就是 80 的多啊...
    aru
        15
    aru  
       2017-01-23 23:19:20 +08:00
    @KCheshireCat
    p2p 下载基本都是非 80 的,而且流量很大。我的大流量应用就是 PT ,经常达到 200Mbps ,估计加上这个会是一个瓶颈。
    今天尝试在 lede ( openwrt fork )上添加项目的 iptables ,找不到 bpf 模块 :(
    KCheshireCat
        16
    KCheshireCat  
    OP
       2017-01-23 23:29:43 +08:00
    @aru
    你需要针对端口限制的话可以在要填"{your WAN}"的那两行加入端口匹配条件.

    然后一般来说容易缺失的 iptables 模块就是 u32 或者 bpf 了,大多数人只是用 iptables 解决些简单的需求,所以不会用到这种需要写字节码的模块.

    不过可以自己编译 openwrt 固件的时候把这几个模块一起编译进去,再或者你可以看看 openwrt 官方源有没有提供补全 iptables 的包,这样就不用自己编译了.
    aru
        17
    aru  
       2017-01-24 00:03:18 +08:00
    @KCheshireCat u32 我编译和加载了, bpf 实在没找到配置选项,网上找了挺多地方,没发现究竟是哪个配置参数
    JJaicmkmy
        18
    JJaicmkmy  
       2017-01-25 20:57:22 +08:00
    @KCheshireCat 如果是自己的服务器的话,可以在服务器上也 DROP 掉 RST 的包,对 SS 有奇效。
    KCheshireCat
        19
    KCheshireCat  
    OP
       2017-01-25 21:01:28 +08:00
    @JJaicmkmy #18
    这么弄的话好像会触发路由黑洞,以前看别人提过。
    Siril
        20
    Siril  
       2017-02-06 14:34:52 +08:00
    awesome idea , but.....
    看 issue ,疑似有误伤,求解惑。
    不知可否在其他发行版复现这个问题
    KCheshireCat
        21
    KCheshireCat  
    OP
       2017-02-06 15:13:00 +08:00   1
    @Siril #20
    目前来说确实有误伤的,这主要和服务器的防火墙策略有一定关系。我在 issue 上做了解释,并提用了使用更宽松规则的临时解决方案。
    但对于问题本身,我还没有更好的想法来解决。
    Siril
        22
    Siril  
       2017-02-06 15:42:17 +08:00
    @KCheshireCat 但愿能找到改进措施。
    ----------
    下面是脑洞:
    仔细考虑后,即使利用 libnetfilter_queue 做出一个,抛开稳定性、吞吐量不谈,
    我感觉按延迟也不靠谱, ack 的时间受目标服务器负载的影响,不能说明问题;
    主动学习数据包长度、 ttl 值 也难免误伤,
    恐怕还要解析数据包内容
    一般也就是内容有固定特征的 302 redirect 、 meta-refresh 、 Javascript 啥的。

    字符串黑名单过滤之。

    思路有了,项目起名叫 WFG 不错。 XD
    KCheshireCat
        23
    KCheshireCat  
    OP
       2017-02-06 16:13:53 +08:00
    @Siril #22
    最早最早的时候我也是用 string 模块过滤字段的,但这么作通用性太差,自己用还不错,写作项目的话以后维护起来会变成又臭又长的规则表,而且对单个用户来说有用的可能就其中的几个。某条规则什么的时候已经失效也没法验证。

    最重要的是运营商改劫持模板方便,我们验证规则,抓包困难。这样十分吃力。
    Siril
        24
    Siril  
       2017-02-06 16:30:23 +08:00
    @KCheshireCat
    前述脑洞是尝试由程序主动学习过滤列表,
    比如说请求许多不同的网站返回相似的结果,
    而非人工维护又臭又长的过滤列表。
    Siril
        25
    Siril  
       2017-02-06 16:38:31 +08:00
    啊不能改自己的回复, 突然想到如果 libnetfilter 可行, 何必玩高级花样。
    既然真正的 response 在假的之后到达,那么假数据包太容易辨认了。
    甚至可否将服务端返回的数据包缓存个多少毫秒超时,如果后续没有就发送这个,后续有“重复”的则 DROP 掉前一个。

    ---------
    可能 proxy server 更适合实现这样的功能。
    akw2312
        26
    akw2312  
       2017-02-19 03:06:25 +08:00
    手的四川移器 有效
    不... 如果劫持是那整 TCP 都劫持走的目也法了吧..
    tcp traceroute 一看都被劫持走的那 (icmp 正常, tcp 非 80 443 8080 也正常)
    Tovcn
        27
    Tovcn  
       2017-07-16 22:51:40 +08:00 via Android
    @Siril 可以写个脚本,让 iptables 把疑似重的包 mark 然后对比包内容,基本一致的就 DROP...
    那有对比包的模块否?
    Tovcn
        28
    Tovcn  
       2017-07-16 22:52:58 +08:00 via Android
    @Siril 可不是写脚本啊。。 。。错了
    siyanmao
        29
    siyanmao  
       2017-08-09 20:49:52 +08:00
    @Siril 我倒是觉得基于延迟判断非常靠谱。延迟最低极限的,而旁路劫持的 RTT 一般很低,通过不断采样 RTT,发现 RTT 急剧减小基本就可以判定是出现劫持了。不过这样要写程序追踪每一个 tcp 流了……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4817 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 09:49 PVG 17:49 LAX 02:49 JFK 05:49
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86