多出口http代理
侧边栏壁纸
  • 累计撰写 8 篇文章
  • 累计收到 0 条评论

多出口http代理

cs76
#
2025-08-05 / 0 评论 / 5 阅读 / 正在检测是否收录...

本方法是 机器带ip4和ip6 并且ip6非常多的那种,脚本会自动轮训网卡上的ip6为出口
适合穷人自建采集

pip install netifaces

如果报错就安装下库

sudo apt update
sudo apt install build-essential
sudo apt install python3-dev
import socket
import threading
import random
import netifaces
import time

# --- 配置 ---
INBOUND_HOST = '0.0.0.0'  # 监听所有IPv4地址
INBOUND_PORT = 5678      # 代理端口

# 白名单IP地址,只允许这些IP连接到代理服务器
# 记得替换成你自己的IP地址
WHITELIST_IPS = [
    '你的白名单IP1',
    '你的白名单IP2',
]

# 指定要读取IPv6地址的网络接口名称
# 确保这个接口是你之前用脚本绑定了大量IPv6地址的接口
IPV6_INTERFACE = 'eth0'

# 全局变量
ipv6_pool = []
current_ip_index = 0
ip_pool_lock = threading.Lock() # 用于线程安全的IP索引更新

def load_ipv6_pool_from_interface(interface_name):
    """从指定的网络接口加载IPv6地址池"""
    pool = []
    try:
        addresses = netifaces.ifaddresses(interface_name)
        if netifaces.AF_INET6 in addresses:
            for link in addresses[netifaces.AF_INET6]:
                ipv6_address = link['addr']
                if not ipv6_address.startswith('fe80::'):
                    if '%' in ipv6_address:
                        ipv6_address = ipv6_address.split('%')[0]
                    pool.append(ipv6_address)
    except ValueError:
        print(f"错误: 找不到网络接口 '{interface_name}'")
    except Exception as e:
        print(f"读取网络接口地址时发生错误: {e}")
    return pool

def get_next_ipv6():
    """获取下一个轮询的IPv6地址"""
    global current_ip_index
    with ip_pool_lock:
        if not ipv6_pool:
            return None
        
        outbound_ipv6 = ipv6_pool[current_ip_index]
        
        # 索引加一,如果到达列表末尾则回到开头
        current_ip_index = (current_ip_index + 1) % len(ipv6_pool)
        
    return outbound_ipv6

def forward_data(sock1, sock2):
    """在两个socket之间转发数据"""
    try:
        while True:
            data = sock1.recv(4096)
            if not data:
                break
            sock2.sendall(data)
    except Exception as e:
        print(f"数据转发错误: {e}")
    finally:
        sock1.close()
        sock2.close()

def handle_client(client_socket):
    """处理客户端连接"""
    outbound_socket = None
    try:
        client_ip = client_socket.getpeername()[0]
        if client_ip not in WHITELIST_IPS:
            print(f"拒绝来自非白名单IP的连接: {client_ip}")
            client_socket.close()
            return
        
        print(f"接受来自 {client_ip} 的连接")
        
        request_line = client_socket.recv(4096).decode('utf-8')
        if not request_line:
            client_socket.close()
            return

        if not request_line.startswith('CONNECT'):
            print(f"不支持的请求方法: {request_line.split(' ')[0]}")
            client_socket.sendall(b'HTTP/1.1 405 Method Not Allowed\r\n\r\n')
            client_socket.close()
            return

        host_port = request_line.split(' ')[1]
        target_host, target_port = host_port.split(':')
        target_port = int(target_port)

        print(f"请求目标: {target_host}:{target_port}")

        outbound_ipv6 = get_next_ipv6()
        if not outbound_ipv6:
            print("错误: IPv6 地址池为空")
            client_socket.close()
            return
        
        print(f"使用出口IP (轮询): {outbound_ipv6}")

        outbound_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
        outbound_socket.bind((outbound_ipv6, 0))
        outbound_socket.connect((target_host, target_port))

        client_socket.sendall(b'HTTP/1.1 200 Connection established\r\n\r\n')

        thread1 = threading.Thread(target=forward_data, args=(client_socket, outbound_socket))
        thread2 = threading.Thread(target=forward_data, args=(outbound_socket, client_socket))
        
        thread1.start()
        thread2.start()
        
        thread1.join()
        thread2.join()

    except Exception as e:
        print(f"处理客户端时发生错误: {e}")
    finally:
        if client_socket:
            client_socket.close()
        if outbound_socket:
            outbound_socket.close()

def main():
    """主函数,启动代理服务器"""
    global ipv6_pool
    ipv6_pool = load_ipv6_pool_from_interface(IPV6_INTERFACE)
    if not ipv6_pool:
        print("警告: IPv6 地址池为空,代理服务器将无法工作。")
        return

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((INBOUND_HOST, INBOUND_PORT))
    server_socket.listen(5)
    print(f"HTTP代理服务器已启动,监听在 {INBOUND_HOST}:{INBOUND_PORT}")
    print(f"已加载 {len(ipv6_pool)} 个IPv6地址作为出口。")

    while True:
        client_socket, addr = server_socket.accept()
        client_thread = threading.Thread(target=handle_client, args=(client_socket,))
        client_thread.start()

if __name__ == '__main__':
    main()
0

评论 (0)

取消