本方法是 机器带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)