import socketserver
import selectors
import struct
import socket
class Socks5_Handler(socketserver.StreamRequestHandler):
def handle_tcp(self, req, remote):
sel = selectors.SelectSelector()
sel.register(req, selectors.EVENT_READ)
sel.register(remote, selectors.EVENT_READ)
while True:
event_list = sel.select()
for key, events in event_list:
conn = key.fileobj
if conn == req:
if remote.send(req.recv(4096)) <= 0:
break
if conn == remote:
if req.send(remote.recv(4096)) <= 0:
break
def handle(self):
try:
print("connect from {0}".format(self.client_address[0]))
# 阶段1:客户端版本协商
self.request.recv(257).strip()
self.request.send(struct.pack("2B", 5, 0))
# 阶段2:解析客户端的请求目标
data = self.request.recv(4).strip()
cmd = data[1]
addr_type = data[3]
if addr_type == 1:
# ipv4 address
address = socket.inet_ntoa(self.request.recv(4).strip())
if addr_type == 3:
# fqdn
lens = ord(self.request.recv(1).strip())
address = self.request.recv(lens).strip()
port = struct.unpack(">H", self.request.recv(2).strip())[0]
# 阶段2:服务端响应
try:
if cmd == 1:
rep2 = struct.pack("4B", 5, 0, 0, 1)
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.connect((address, port))
else:
rep2 = struct.pack("4B", 5, 7, 0, 1)
local = remote.getsockname()
rep2 += socket.inet_aton(local[0]) + struct.pack(">H", local[1])
except socket.error:
rep2 = struct.pack("10B", 5, 3, 0, 1, 0, 0, 0, 0, 0, 0)
self.request.send(rep2)
# 阶段3:流量转发
if rep2[1] == 0:
self.handle_tcp(self.request, remote)
else:
self.request.shutdown(socket.SHUT_RDWR)
self.request.close()
except Exception as e:
print(e)
def main(host, port):
server = socketserver.ThreadingTCPServer((host, port), Socks5_Handler)
server.serve_forever()
if __name__ == "__main__":
HOST = "127.0.0.1"
PORT = 1080
main(HOST, PORT)