一个简单的Python脚本实现SOCKS5代理服务器的基本功能

以下是一个简单的Python脚本,实现了SOCKS5代理服务器的基本功能:

import socket
import select

class Socks5Proxy:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def 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:
                        continue
                    client_socket.sendall(b"\x05\x00")

                    # 请求阶段
                    data = client_socket.recv(1024)
                    if not data:
                        continue
                    version = data[0]
                    command = data[1]
                    address_type = data[3]
                    if address_type == 1:  # IPv4
                        address = 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()
                        continue

                    bind_address = remote_socket.getsockname()
                    bind_address_type = 1  # 只支持IPv4
                    bind_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_bytes
                    client_socket.sendall(response)

                    # 转发阶段
                    sockets = [client_socket, remote_socket]
                    while True:
                        rlist, wlist, xlist = select.select(sockets, [], sockets, 5)
                        if xlist:
                            break
                        for rsock in rlist:
                            wsock = remote_socket if rsock is client_socket else client_socket
                            data = rsock.recv(4096)
                            if not data:
                                sockets.remove(rsock)
                                continue
                            wsock.sendall(data)

                    print(f"Closed connection from {client_address}")

if __name__ == "__main__":
    proxy = Socks5Proxy("0.0.0.0", 1080)
    proxy.run()

以上代码中,我们创建了一个Socks5Proxy类,它继承自object类。我们在类的构造函数中指定了代理服务器的主机和端口。在run方法中,我们创建了一个socket对象,并将其绑定到指定的主机和端口上。然后,我们使用循环来接受客户端的连接,并在每个连接上执行以下步骤:

握手阶段:接收客户端发送的握手请求,并向客户端发送握手响应。

请求阶段:接收客户端发送的请求,并解析出请求的目标地址和端口号。

响应阶段:向客户端发送请求响应,并建立与目标服务器的连接。

转发阶段:使用select模块来实现双向数据传输,将客户端和目标服务器之间的数据互相转发。

最后,我们在main函数中创建了一个Socks5Proxy对象,并调用其run方法来启动代理服务器。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值