From 0a2787f316c2238c52f257e703aae16e4116ad45 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 16 Apr 2024 16:59:53 +0800 Subject: [PATCH] first commit --- README.md | 38 +++++++++++++++++++++++++++++++++++ geneva.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100755 README.md create mode 100755 geneva.py diff --git a/README.md b/README.md new file mode 100755 index 0000000..6068290 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# 前言 +这俩天移动升级了策略,之前的过移动策略针对HTTP方式已经有大部分地区失效了,墙在升级,所以我们策略也得改变。之前版本的4字节分割貌似被移动针对了,我开始怀疑移动是不是已经整上了tcp报文重组。 +测试了1-20的窗口值,窗口值在(1-4)时,屏蔽很严重,这里应该是移动重点处理的地方。 +当我测试窗口值为6时,发现绝大部分地区的移动竟然可以过了。接着陆续测试了窗口值(7-16),发现屏蔽比在区间(1-4)时要好,但大差不差。 +使用窗口值为17时测试时,神奇的事情发生了,它竟然全过了。没错,还是原来的4字节分割的味道。只不过这次以17字节出现。继续往上测试,发现窗口值20也能过。 +目前我也是知其然不知其所以然的状态,我后续会针对移动做更严谨的测试,期望得到更多此次升级的特点并总结原理。 +# 用途 +绕过国内移动线路的运营商屏蔽、国内免备案 + +## 注意事项 +此项目由Python编写,只适用于小型和低带宽的网站。如果你的网站流量大或资源需求多,使用此程序**可能会导致网站宕机**,所以大型网站或资源需求高的情况下请慎用。 + +中大型网站建议使用商业版本,强劲的性能和稳定性,以充分利用服务器的性能,特别是在结合CDN使用时。 + +对于这个项目如果有任何疑问或者提议,欢迎通过telegram与我直接沟通[点击这里联系我](https://t.me/milk553) + + +# CentOS --建议使用centos7 +yum install -y python3 python3-devel gcc gcc-c++ git libnetfilter* libffi-devel + +pip3 install --upgrade pip + +pip3 install scapy netfilterqueue + +# Ubuntu --建议使用Ubuntu 22 + +sudo apt-get install build-essential python3-dev libnetfilter-queue-dev libffi-dev libssl-dev iptables python3-pip -y + +pip3 install scapy netfilterqueue + +# 运行程序 +git clone https://github.com/milk192/pygeneva.git + +cd pygeneva + +nohup python3 geneva.py -q 100 -w 4 & + +iptables -I OUTPUT -p tcp -m multiport --sports 80,443 --tcp-flags SYN,RST,ACK,FIN,PSH SYN,ACK -j NFQUEUE --queue-num 100 \ No newline at end of file diff --git a/geneva.py b/geneva.py new file mode 100755 index 0000000..c334b27 --- /dev/null +++ b/geneva.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import os +import signal +from scapy.all import * +from netfilterqueue import NetfilterQueue +import argparse + +window_size = 20 + +def modify_window(pkt): + try: + ip = IP(pkt.get_payload()) + if ip.haslayer(TCP) and ip[TCP].flags == "SA": + ip[TCP].window = window_size + del ip[IP].chksum + del ip[TCP].chksum + pkt.set_payload(bytes(ip)) + elif ip.haslayer(TCP) and ip[TCP].flags == "FA": + ip[TCP].window = window_size + del ip[IP].chksum + del ip[TCP].chksum + pkt.set_payload(bytes(ip)) + elif ip.haslayer(TCP) and ip[TCP].flags == "PA": + ip[TCP].window = window_size + del ip[IP].chksum + del ip[TCP].chksum + pkt.set_payload(bytes(ip)) + elif ip.haslayer(TCP) and ip[TCP].flags == "A": + ip[TCP].window = window_size + del ip[IP].chksum + del ip[TCP].chksum + pkt.set_payload(bytes(ip)) + except: + pass + + pkt.accept() + +def parsearg(): + parser = argparse.ArgumentParser(description='Description of your program') + + parser.add_argument('-q', '--queue', type=int, help='iptables Queue Num') + parser.add_argument('-w', '--window_size', type=int, help='Tcp Window Size') + + args = parser.parse_args() + + if args.queue is None or args.window_size is None: + exit(1) + + window_size = args.window_size + + return args.queue + +def main(): + queue_num = parsearg() + nfqueue = NetfilterQueue() + nfqueue.bind(queue_num, modify_window) + + try: + print("Starting netfilter_queue process...") + nfqueue.run() + except KeyboardInterrupt: + pass + +if __name__ == "__main__": + #sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + signal.signal(signal.SIGINT, lambda signal, frame: sys.exit(0)) + main()