#!/usr/bin/env python3 """ Webshare 代理管理器 通过 Tailscale 连接甲骨文节点进行代理中转 """ import subprocess import time import threading import json import requests from concurrent.futures import ThreadPoolExecutor class ProxyManager: def __init__(self, oracle_ip): self.oracle_ip = oracle_ip self.local_start_port = 20001 self.oracle_start_port = 10001 self.proxy_count = 20 self.processes = [] def start_local_forwards(self): """启动本地转发""" print(f"启动本地代理转发到甲骨文服务器 {self.oracle_ip}") # 清理之前的进程 self.stop_forwards() for i in range(self.proxy_count): local_port = self.local_start_port + i oracle_port = self.oracle_start_port + i cmd = [ 'gost', '-L', f'socks5://127.0.0.1:{local_port}', '-F', f'socks5://{self.oracle_ip}:{oracle_port}' ] try: process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.processes.append(process) print(f"本地端口 {local_port} -> 甲骨文 {self.oracle_ip}:{oracle_port}") time.sleep(0.1) except Exception as e: print(f"启动转发失败 {local_port}: {e}") print(f"已启动 {len(self.processes)} 个代理转发") def stop_forwards(self): """停止所有转发""" for process in self.processes: try: process.terminate() process.wait(timeout=5) except: try: process.kill() except: pass self.processes.clear() # 额外清理 try: subprocess.run(['pkill', '-f', 'gost.*:2000'], check=False) except: pass def test_proxy(self, port): """测试单个代理""" try: proxy = f'socks5://127.0.0.1:{port}' response = requests.get( 'http://httpbin.org/ip', proxies={'http': proxy, 'https': proxy}, timeout=10 ) if response.status_code == 200: ip = response.json().get('origin', 'Unknown') return port, True, ip except Exception as e: return port, False, str(e) return port, False, 'Timeout' def test_all_proxies(self): """测试所有代理""" print("测试代理连接...") ports = [self.local_start_port + i for i in range(self.proxy_count)] with ThreadPoolExecutor(max_workers=10) as executor: results = list(executor.map(self.test_proxy, ports)) working = 0 failed = 0 for port, success, info in results: if success: print(f"✓ 端口 {port}: {info}") working += 1 else: print(f"✗ 端口 {port}: {info}") failed += 1 print(f"\n测试结果: {working} 个工作, {failed} 个失败") return working, failed def generate_clash_config(self): """生成 Clash 配置""" config = { 'port': 7890, 'socks-port': 7891, 'allow-lan': True, 'mode': 'Rule', 'log-level': 'info', 'external-controller': '127.0.0.1:9090', 'proxies': [], 'proxy-groups': [], 'rules': ['MATCH,WebShare'] } # 添加代理 for i in range(self.proxy_count): port = self.local_start_port + i config['proxies'].append({ 'name': f'WebShare-{i+1}', 'type': 'socks5', 'server': '127.0.0.1', 'port': port }) # 选择组 proxy_names = [f'WebShare-{i+1}' for i in range(self.proxy_count)] config['proxy-groups'].append({ 'name': 'WebShare', 'type': 'select', 'proxies': proxy_names }) # 负载均衡组 config['proxy-groups'].append({ 'name': 'LoadBalance', 'type': 'load-balance', 'url': 'http://www.gstatic.com/generate_204', 'interval': 300, 'proxies': proxy_names }) # 保存配置 with open('clash-webshare-auto.yaml', 'w') as f: import yaml yaml.dump(config, f, default_flow_style=False) print("Clash 配置已生成: clash-webshare-auto.yaml") def run(self): """运行管理器""" try: self.start_local_forwards() time.sleep(2) # 等待连接建立 working, failed = self.test_all_proxies() if working > 0: self.generate_clash_config() print(f"\n可用代理端口: 127.0.0.1:{self.local_start_port}-{self.local_start_port + working - 1}") print("\n按 Ctrl+C 停止...") while True: time.sleep(60) # 定期检查 print(".", end="", flush=True) else: print("没有可用的代理连接") except KeyboardInterrupt: print("\n正在停止...") finally: self.stop_forwards() def main(): import sys if len(sys.argv) != 2: print("使用方法: python3 proxy-manager.py <甲骨文Tailscale IP>") print("示例: python3 proxy-manager.py 100.64.0.1") sys.exit(1) oracle_ip = sys.argv[1] manager = ProxyManager(oracle_ip) manager.run() if __name__ == "__main__": main()