必须 python3.6.x Centos7.x 安装(环境) yum install -y python3 python3-devel gcc gcc-c++ git libnetfilter* libffi-devel git clone https://github.com/Kkevsterrr/geneva.git cd geneva/ python3 -m pip install -r requirements.txt Debian10.x 安装(环境) git clone https://github.com/Kkevsterrr/geneva.git cd geneva/ apt-get install build-essential python-dev libnetfilter-queue-dev libffi-dev libssl-dev iptables python3-pip python3 -m pip install -r requirements.txt 四节分流法 nohup python3 engine.py --server-port 80 --strategy "[TCP:flags:SA]-tamper{TCP:window:replace:0}-|" --log debug --server-side >/dev/null 2>&1 & nohup python3 engine.py --server-port 80 --strategy "[TCP:flags:A]-tamper{TCP:window:replace:0}-|" --log debug --in-queue-num 3 --out-queue-num 4 --server-side >/dev/null 2>&1 & nohup python3 engine.py --server-port 80 --strategy "[TCP:flags:PA]-tamper{TCP:window:replace:0}-|" --log debug --in-queue-num 5 --out-queue-num 6 --server-side >/dev/null 2>&1 & nohup python3 engine.py --server-port 80 --strategy "[TCP:flags:FA]-tamper{TCP:window:replace:0}-|" --log debug --in-queue-num 7 --out-queue-num 8 --server-side >/dev/null 2>&1 & 全部启动后(大概 5秒) iptables -F iptables -A OUTPUT -p tcp --sport 80 --tcp-flags SYN,RST,ACK,FIN,PSH SYN,ACK -j NFQUEUE --queue-num 2 iptables -A OUTPUT -p tcp --sport 80 --tcp-flags SYN,RST,ACK,FIN,PSH ACK -j NFQUEUE --queue-num 4 iptables -A OUTPUT -p tcp --sport 80 --tcp-flags SYN,RST,ACK,FIN,PSH PSH,ACK -j NFQUEUE --queue-num 6 iptables -A OUTPUT -p tcp --sport 80 --tcp-flags SYN,RST,ACK,FIN,PSH FIN,ACK -j NFQUEUE --queue-num 8 启动80端口 nohup python3 xxx.py >/dev/null 2>&1 & 代码如下 # coding: utf8 import socketserver import socket class TCPHandler(socketserver.BaseRequestHandler): # 重写handle方法 def handle(self): while True: try: data = { "Http_Status": "HTTP/1.1 301 ok", "Content-Type": "text/html; charset=utf-8", "Location": "https://baidu.com/", # "Html": 'JS跳转html代码', # 如果需要,注销上行"Location",下面 self.data 修改为注释行 } self.data = bytes("{0}\r\nContent-Type: {1}\r\nLocation: {2}\r\n".format( \ data['Http_Status'],data['Content-Type'],data['Location']), 'ascii') #self.data = bytes("{0}\r\nContent-Type: {1}\r\n\r\n{2}".format( \ # data['Http_Status'],data['Content-Type'], data['Html']), 'ascii') # self.server.allow_reuse_address = True self.server.request_queue_size = 1024 self.server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.request.sendall(self.data) break except ConnectionResetError as e: print(self.client_address, e) break if __name__ == '__main__': HOST, PORT = '0.0.0.0', 80 with socketserver.ThreadingTCPServer((HOST, PORT), TCPHandler) as server: server.serve_forever() 不同域名跳转不同地址 可能你有多个域名,但是跳转不一样? 可能你需要跳转后的路径、参数不变? 看这里,统统解决!!! # coding: utf8 import socketserver import socket class TCPHandler(socketserver.BaseRequestHandler): # 重写handle方法 def handle(self): while True: try: data = { "Http_Status": "HTTP/1.1 200 ok", "Content-Type": "text/html; charset=utf-8", # "Location": "https://baidu.com/", "Html": '''<html> <head></head> <body> <a href="" id="hao123"></a> <script type="text/javascript"> var arr = { '1.xxx.com': 'https://baidu.com', '2.xxx.com': 'http://qq.com', } var strU = arr[window.location.hostname]+window.location.pathname+window.location.search; hao123.href=strU; if(document.all){ document.getElementById("hao123").click(); }else { var e=document.createEvent("MouseEvents"); e.initEvent("click",true,true); document.getElementById("hao123").dispatchEvent(e); } </script> </body> </html>''', # 如果需要,注销上行"Location",下面 self.data 修改为注释行 } # self.data = bytes("{0}\r\nContent-Type: {1}\r\nLocation: {2}\r\n".format( \ # data['Http_Status'],data['Content-Type'],data['Location']), 'ascii') self.data = bytes("{0}\r\nContent-Type: {1}\r\n\r\n{2}".format( \ data['Http_Status'],data['Content-Type'], data['Html']), 'ascii') # self.server.allow_reuse_address = True self.server.request_queue_size = 1024 self.server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.request.sendall(self.data) break except ConnectionResetError as e: print(self.client_address, e) break if __name__ == '__main__': HOST, PORT = '0.0.0.0', 80 with socketserver.ThreadingTCPServer((HOST, PORT), TCPHandler) as server: server.serve_forever() 参考: https://github.com/kkevsterrr/geneva 参考: https://2047.name/t/16483 参考: https://gfw.report/blog/gfw_esni_blocking/zh/ 参考: https://github.com/lehui99/articles/blob/main/301%E6%B5%B7%E5%A4%96%E8%B7%B3%E8%BD%AC%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90%E5%85%BC%E8%B0%88%E7%BC%93%E8%A7%A3%E5%81%87%E5%A2%99%E4%BC%AA%E5%A2%99%E6%94%BB%E5%87%BB%E5%8B%92%E7%B4%A2%E7%9A%84%E5%A4%9A%E7%A7%8D%E6%8A%80%E6%9C%AF%E6%89%8B%E6%AE%B5%EF%BC%88%E4%BA%8C%EF%BC%89.md 电报群: https://t.me/davidtechtalk |