发布时间:2025-12-09 16:26:52 浏览次数:3
以下是一个简单的Python脚本,实现了SOCKS5代理服务器的基本功能:
import socketimport selectclass Socks5Proxy:def __init__(self, host, port):self.host = hostself.port = portdef run(self):with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)server_socket.bind((self.host, self.port))server_socket.listen()print(f"SOCKS5 proxy is listening on {self.host}:{self.port}...")while True:client_socket, client_address = server_socket.accept()print(f"Accepted connection from {client_address}")with client_socket:# 握手阶段data = client_socket.recv(1024)if not data:continueclient_socket.sendall(b"\x05\x00")# 请求阶段data = client_socket.recv(1024)if not data:continueversion = data[0]command = data[1]address_type = data[3]if address_type == 1: # IPv4address = socket.inet_ntoa(data[4:8])port = int.from_bytes(data[8:], byteorder="big")elif address_type == 3: # 域名address_length = data[4]address = data[5:5+address_length].decode("utf-8")port = int.from_bytes(data[5+address_length:], byteorder="big")else:client_socket.close()continue# 响应阶段try:remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)remote_socket.connect((address, port))except Exception as e:client_socket.sendall(b"\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00")client_socket.close()continuebind_address = remote_socket.getsockname()bind_address_type = 1 # 只支持IPv4bind_address_bytes = socket.inet_aton(bind_address[0])bind_port_bytes = bind_address[1].to_bytes(2, byteorder="big")response = bytearray([version, 0x00, 0x00, bind_address_type])response += bind_address_bytes + bind_port_bytesclient_socket.sendall(response)# 转发阶段sockets = [client_socket, remote_socket]while True:rlist, wlist, xlist = select.select(sockets, [], sockets, 5)if xlist:breakfor rsock in rlist:wsock = remote_socket if rsock is client_socket else client_socketdata = rsock.recv(4096)if not data:sockets.remove(rsock)continuewsock.sendall(data)print(f"Closed connection from {client_address}")if __name__ == "__main__":proxy = Socks5Proxy("0.0.0.0", 1080)proxy.run()握手阶段:接收客户端发送的握手请求,并向客户端发送握手响应。
请求阶段:接收客户端发送的请求,并解析出请求的目标地址和端口号。
响应阶段:向客户端发送请求响应,并建立与目标服务器的连接。
转发阶段:使用select模块来实现双向数据传输,将客户端和目标服务器之间的数据互相转发。
最后,我们在main函数中创建了一个Socks5Proxy对象,并调用其run方法来启动代理服务器。