webshare/proxy-manager.py

192 lines
5.9 KiB
Python
Executable File

#!/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()