This commit is contained in:
WebShare Proxy Bot 2025-10-09 01:21:44 +00:00
parent fc791e1d61
commit 169196a372
17 changed files with 1306 additions and 0 deletions

28
.kiro/steering/product.md Normal file
View File

@ -0,0 +1,28 @@
---
inclusion: always
---
# Product Overview
This is a proxy management tool that fetches proxy lists from Webshare API and generates configuration files for multiple proxy clients.
## Core Functionality
- Fetches SOCKS/HTTP proxies from Webshare.io API using download tokens
- Supports multiple output formats: raw, HTTP, SOCKS5
- Generates configuration files for popular proxy clients:
- Clash (YAML format)
- SingBox (JSON format)
- V2Ray (JSON config + Base64 subscription)
## Key Features
- Automatic API key management from `.env` file or environment variables
- Multiple authentication methods (username/password, IP auth)
- Country and location filtering support
- Automatic proxy health checking and failover configurations
- Chinese language support with UTF-8 encoding
## Target Users
Developers and users who need to manage proxy configurations across different clients and platforms, particularly those requiring access to geo-restricted content or enhanced privacy.

View File

@ -0,0 +1,52 @@
---
inclusion: always
---
# Project Structure
## Root Directory Layout
```
├── fetch_proxies.py # Main Python script - core functionality
├── pr.sh # Shell script for manual API testing
├── .env # Environment variables (API keys)
├── user_info.txt # User account information
├── README.md # Project documentation
└── .gitignore # Git ignore rules
```
## Generated Output Files
```
├── proxies_raw.txt # Raw proxy format (host:port:user:pass)
├── proxies_http.txt # HTTP proxy URLs
├── proxies_socks5.txt # SOCKS5 proxy URLs
├── clash_config.yaml # Clash client configuration
├── singbox_config.json # SingBox client configuration
├── v2ray_config.json # V2Ray client configuration
└── v2ray_subscription.txt # Base64 encoded V2Ray subscription
```
## Code Organization
### Main Script (`fetch_proxies.py`)
- **API Functions**: `load_api_key()`, `get_download_token()`, `download_proxies()`
- **Parsing Functions**: `parse_proxies()`, `format_proxy_list()`
- **Output Functions**: `save_proxies()`, `save_*_config()` for each client type
- **Config Generators**: `generate_clash_config()`, `generate_singbox_config()`, `generate_v2ray_config()`
### Configuration Patterns
- All functions use UTF-8 encoding
- Error handling with descriptive Chinese messages
- Modular design - each client type has dedicated generator functions
- Consistent proxy data structure: `{'host', 'port', 'username', 'password'}`
## File Naming Conventions
- Snake_case for Python files and generated outputs
- Descriptive prefixes: `proxies_*` for proxy lists, `*_config.*` for client configs
- Standard extensions: `.py`, `.yaml`, `.json`, `.txt`, `.sh`
## Environment Management
- `.env` file for sensitive API keys
- Environment variables as fallback: `TOKEN` or `WEBSHARE_API_KEY`
- All sensitive data excluded from version control via `.gitignore`

56
.kiro/steering/tech.md Normal file
View File

@ -0,0 +1,56 @@
---
inclusion: always
---
# Technology Stack
## Language & Runtime
- **Python 3**: Main scripting language with UTF-8 encoding support
- **Bash**: Shell scripting for automation
## Dependencies
- `requests`: HTTP client for API calls
- `yaml`: YAML configuration file generation
- `json`: JSON configuration handling
- `base64`: Encoding for V2Ray subscriptions
- `os`: Environment variable and file system operations
## Configuration Formats
- **YAML**: Clash proxy client configurations
- **JSON**: SingBox and V2Ray configurations
- **Plain text**: Raw proxy lists in various formats
- **Base64**: V2Ray subscription links
## Common Commands
### Setup
```bash
# Install dependencies (if using pip)
pip install requests pyyaml
# Set up environment
echo "TOKEN=your_webshare_api_key" > .env
```
### Execution
```bash
# Run the main proxy fetcher
python3 fetch_proxies.py
# Quick API test (manual)
bash pr.sh
```
### Output Files Generated
- `proxies_raw.txt`: Raw format (host:port:username:password)
- `proxies_http.txt`: HTTP format URLs
- `proxies_socks5.txt`: SOCKS5 format URLs
- `clash_config.yaml`: Clash client configuration
- `singbox_config.json`: SingBox client configuration
- `v2ray_config.json`: V2Ray client configuration
- `v2ray_subscription.txt`: Base64 encoded subscription
## API Integration
- **Webshare.io API v2**: Primary proxy source
- Token-based authentication with download tokens
- RESTful endpoints for proxy list retrieval

165
SETUP-GUIDE.md Normal file
View File

@ -0,0 +1,165 @@
# Webshare 代理通过 Tailscale + 甲骨文中转设置指南
## 架构说明
```
本地应用 → 本地SOCKS5(20001-20020) → Tailscale → 甲骨文节点(10001-10020) → Webshare代理
```
## 前置要求
1. 甲骨文服务器已安装 Tailscale 并连接到您的网络
2. 本地机器也已安装 Tailscale 并连接到同一网络
3. 两台机器都能正常通信
## 设置步骤
### 第一步:甲骨文服务器设置
1. 将 `oracle-server-setup.sh` 上传到甲骨文服务器:
```bash
scp oracle-server-setup.sh user@your-oracle-server:~/
```
2. 在甲骨文服务器上运行:
```bash
chmod +x oracle-server-setup.sh
./oracle-server-setup.sh
```
3. 启动代理中转服务:
```bash
cd ~/proxy-config
./start-proxy-relay.sh
```
4. 记下显示的 Tailscale IP 地址100.64.0.1
### 第二步:本地设置
1. 运行本地客户端设置:
```bash
./local-client-setup.sh
```
输入甲骨文服务器的 Tailscale IP
2. 启动本地转发:
```bash
./start-local-forward.sh
```
3. 测试连接:
```bash
./test-proxies.sh
```
### 第三步:使用 Python 管理器(推荐)
更简单的方式是使用 Python 管理器:
```bash
# 安装依赖
pip3 install requests pyyaml
# 启动管理器(替换为实际的甲骨文 Tailscale IP
python3 proxy-manager.py 100.64.0.1
```
管理器会自动:
- 启动所有代理转发
- 测试连接状态
- 生成 Clash 配置文件
## 使用方式
### 直接使用 SOCKS5 代理
```bash
# 测试代理
curl --socks5 127.0.0.1:20001 http://httpbin.org/ip
# 使用不同代理
curl --socks5 127.0.0.1:20002 http://httpbin.org/ip
```
### 使用 Clash
```bash
# 使用生成的配置启动 Clash
clash -f clash-webshare-config.yaml
# 或使用自动生成的配置
clash -f clash-webshare-auto.yaml
```
### 在应用中使用
- **浏览器**:设置 SOCKS5 代理为 `127.0.0.1:20001-20020`
- **curl**`curl --socks5 127.0.0.1:20001 URL`
- **Python requests**
```python
proxies = {
'http': 'socks5://127.0.0.1:20001',
'https': 'socks5://127.0.0.1:20001'
}
requests.get('http://example.com', proxies=proxies)
```
## 端口分配
| 服务 | 端口范围 | 说明 |
|------|----------|------|
| 甲骨文中转 | 10001-10020 | 接收本地连接,转发到 Webshare |
| 本地代理 | 20001-20020 | 本地应用连接这些端口 |
| Clash HTTP | 7890 | Clash HTTP 代理端口 |
| Clash SOCKS | 7891 | Clash SOCKS 代理端口 |
## 故障排除
### 1. 连接失败
- 检查 Tailscale 连接:`tailscale status`
- 检查甲骨文服务器防火墙
- 确认甲骨文服务器代理服务正在运行
### 2. 代理不工作
- 检查 Webshare 账号状态
- 测试单个 Webshare 代理是否可用
- 查看 gost 进程是否正常运行:`ps aux | grep gost`
### 3. 性能优化
- 根据需要调整代理数量
- 使用负载均衡模式分散请求
- 监控代理使用情况
## 管理命令
```bash
# 查看运行状态
ps aux | grep gost
# 停止所有代理
pkill -f gost
# 重启服务(在甲骨文)
cd ~/proxy-config && ./start-proxy-relay.sh
# 重启本地转发
./start-local-forward.sh
```
## 安全注意事项
1. 确保 Tailscale 网络安全
2. 不要将代理端口暴露到公网
3. 定期更新 Webshare 账号凭证
4. 监控代理使用情况,避免滥用
## 自动化启动
### 甲骨文服务器systemd 服务)
```bash
sudo systemctl enable webshare-proxy
sudo systemctl start webshare-proxy
```
### 本地(可选)
创建开机启动脚本或使用 crontab。
---
**提示**:首次设置建议先手动运行各个步骤,确认工作正常后再设置自动启动。

0
fetch_proxies.py Normal file → Executable file
View File

148
local-client-setup.sh Executable file
View File

@ -0,0 +1,148 @@
#!/bin/bash
echo "=== 本地客户端设置 ==="
# 配置你的甲骨文 Tailscale IP
ORACLE_IP="100.x.x.x" # 请替换为实际的甲骨文 Tailscale IP
echo "请先设置甲骨文服务器的 Tailscale IP:"
read -p "输入甲骨文服务器的 Tailscale IP: " ORACLE_IP
if [ -z "$ORACLE_IP" ]; then
echo "IP 地址不能为空"
exit 1
fi
# 1. 安装 gost如果没有
echo "检查 gost..."
if ! command -v gost &> /dev/null; then
echo "安装 gost..."
wget -O gost.gz https://github.com/ginuerzh/gost/releases/download/v2.11.5/gost-linux-amd64-2.11.5.gz
gunzip gost.gz
chmod +x gost-linux-amd64-2.11.5
sudo mv gost-linux-amd64-2.11.5 /usr/local/bin/gost
echo "gost 安装完成"
fi
# 2. 创建本地转发脚本
cat > start-local-forward.sh << EOF
#!/bin/bash
echo "启动本地代理转发..."
echo "甲骨文服务器: $ORACLE_IP"
# 杀死之前的进程
pkill -f "gost.*:2000"
# 启动20个本地转发
for i in {1..20}; do
local_port=\$((20000 + i))
oracle_port=\$((10000 + i))
# 本地端口 -> 甲骨文端口
gost -L "socks5://127.0.0.1:\$local_port" -F "socks5://$ORACLE_IP:\$oracle_port" &
echo "本地端口 \$local_port -> 甲骨文 $ORACLE_IP:\$oracle_port"
sleep 0.1
done
echo ""
echo "本地代理转发已启动!"
echo "SOCKS5 代理地址: 127.0.0.1:20001-20020"
echo ""
echo "测试命令:"
echo "curl --socks5 127.0.0.1:20001 http://httpbin.org/ip"
echo ""
echo "按 Ctrl+C 停止"
wait
EOF
chmod +x start-local-forward.sh
# 3. 创建测试脚本
cat > test-proxies.sh << 'EOF'
#!/bin/bash
echo "测试代理连接..."
for i in {1..5}; do # 只测试前5个
port=$((20000 + i))
echo -n "测试端口 $port: "
result=$(timeout 10 curl -s --socks5 127.0.0.1:$port http://httpbin.org/ip 2>/dev/null | jq -r '.origin' 2>/dev/null)
if [ -n "$result" ]; then
echo "$result"
else
echo "✗ 连接失败"
fi
done
EOF
chmod +x test-proxies.sh
# 4. 创建 Clash 配置
cat > clash-webshare-config.yaml << 'EOF'
port: 7890
socks-port: 7891
allow-lan: true
mode: Rule
log-level: info
external-controller: 127.0.0.1:9090
proxies:
EOF
for i in {1..20}; do
port=$((20000 + i))
cat >> clash-webshare-config.yaml << EOF
- name: "WebShare-$i"
type: socks5
server: 127.0.0.1
port: $port
EOF
done
cat >> clash-webshare-config.yaml << 'EOF'
proxy-groups:
- name: "WebShare"
type: select
proxies:
EOF
for i in {1..20}; do
echo " - \"WebShare-$i\"" >> clash-webshare-config.yaml
done
cat >> clash-webshare-config.yaml << 'EOF'
- name: "LoadBalance"
type: load-balance
url: http://www.gstatic.com/generate_204
interval: 300
proxies:
EOF
for i in {1..20}; do
echo " - \"WebShare-$i\"" >> clash-webshare-config.yaml
done
cat >> clash-webshare-config.yaml << 'EOF'
rules:
- MATCH,WebShare
EOF
echo ""
echo "=== 设置完成 ==="
echo ""
echo "使用步骤:"
echo "1. 确保甲骨文服务器已启动代理中转"
echo "2. 运行: ./start-local-forward.sh"
echo "3. 测试: ./test-proxies.sh"
echo "4. 使用 Clash: clash -f clash-webshare-config.yaml"
echo ""
echo "本地 SOCKS5 代理: 127.0.0.1:20001-20020"

88
local-webshare-forward.py Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""
将本地 webshare SOCKS5 代理通过 Tailscale 转发到甲骨文节点
"""
import subprocess
import json
import time
import threading
# 配置
ORACLE_TAILSCALE_IP = "100.x.x.x" # 替换为你的甲骨文 Tailscale IP
WEBSHARE_PROXIES_FILE = "webshare_proxies.txt" # webshare 代理列表文件
LOCAL_START_PORT = 20001 # 本地监听起始端口
def read_webshare_proxies():
"""读取 webshare 代理列表"""
proxies = []
try:
with open(WEBSHARE_PROXIES_FILE, 'r') as f:
for line in f:
line = line.strip()
if line and ':' in line:
# 格式: ip:port:username:password
parts = line.split(':')
if len(parts) >= 4:
proxies.append({
'host': parts[0],
'port': parts[1],
'username': parts[2],
'password': parts[3]
})
except FileNotFoundError:
print(f"请创建 {WEBSHARE_PROXIES_FILE} 文件,每行一个代理: ip:port:username:password")
return []
return proxies[:20] # 只取前20个
def start_proxy_forward(local_port, oracle_port, webshare_proxy):
"""启动单个代理转发"""
# 使用 gost 进行代理链转发
cmd = f"""gost -L socks5://:{local_port} -F socks5://{webshare_proxy['username']}:{webshare_proxy['password']}@{webshare_proxy['host']}:{webshare_proxy['port']}"""
print(f"启动本地端口 {local_port} -> 甲骨文 {oracle_port} -> webshare {webshare_proxy['host']}:{webshare_proxy['port']}")
try:
subprocess.run(cmd, shell=True)
except Exception as e:
print(f"代理转发失败 {local_port}: {e}")
def main():
# 读取 webshare 代理列表
webshare_proxies = read_webshare_proxies()
if not webshare_proxies:
print("没有找到有效的 webshare 代理配置")
return
print(f"找到 {len(webshare_proxies)} 个 webshare 代理")
# 启动代理转发
threads = []
for i, proxy in enumerate(webshare_proxies):
local_port = LOCAL_START_PORT + i
oracle_port = 10001 + i
thread = threading.Thread(
target=start_proxy_forward,
args=(local_port, oracle_port, proxy)
)
thread.daemon = True
thread.start()
threads.append(thread)
time.sleep(0.1) # 避免启动过快
print(f"已启动 {len(threads)} 个代理转发")
print(f"本地 SOCKS5 代理端口: {LOCAL_START_PORT}-{LOCAL_START_PORT + len(webshare_proxies) - 1}")
# 等待所有线程
try:
for thread in threads:
thread.join()
except KeyboardInterrupt:
print("\n正在停止代理转发...")
if __name__ == "__main__":
main()

28
oracle-proxy-config.json Normal file
View File

@ -0,0 +1,28 @@
{
"Debug": false,
"Retries": 3,
"ServeNodes": [
"socks5://:10001",
"socks5://:10002",
"socks5://:10003",
"socks5://:10004",
"socks5://:10005",
"socks5://:10006",
"socks5://:10007",
"socks5://:10008",
"socks5://:10009",
"socks5://:10010",
"socks5://:10011",
"socks5://:10012",
"socks5://:10013",
"socks5://:10014",
"socks5://:10015",
"socks5://:10016",
"socks5://:10017",
"socks5://:10018",
"socks5://:10019",
"socks5://:10020"
],
"ChainNodes": [],
"Routes": []
}

124
oracle-server-setup.sh Executable file
View File

@ -0,0 +1,124 @@
#!/bin/bash
echo "=== 甲骨文服务器代理中转设置 ==="
# 1. 安装 gost
echo "安装 gost..."
if ! command -v gost &> /dev/null; then
wget -O gost.gz https://github.com/ginuerzh/gost/releases/download/v2.11.5/gost-linux-amd64-2.11.5.gz
gunzip gost.gz
chmod +x gost-linux-amd64-2.11.5
sudo mv gost-linux-amd64-2.11.5 /usr/local/bin/gost
echo "gost 安装完成"
else
echo "gost 已安装"
fi
# 2. 确保 Tailscale 已安装并运行
if ! command -v tailscale &> /dev/null; then
echo "请先安装 Tailscale:"
echo "curl -fsSL https://tailscale.com/install.sh | sh"
echo "sudo tailscale up"
exit 1
fi
# 3. 获取 Tailscale IP
TAILSCALE_IP=$(tailscale ip -4)
echo "甲骨文服务器 Tailscale IP: $TAILSCALE_IP"
# 4. 创建代理配置目录
mkdir -p ~/proxy-config
cd ~/proxy-config
# 5. 创建 webshare 代理列表
cat > webshare-proxies.txt << 'EOF'
fbkjstyt:lvo4zphp2wwj@45.196.40.191:6269
fbkjstyt:lvo4zphp2wwj@130.180.228.168:6452
fbkjstyt:lvo4zphp2wwj@72.1.154.35:7926
fbkjstyt:lvo4zphp2wwj@63.141.62.186:6479
fbkjstyt:lvo4zphp2wwj@216.170.122.181:6219
fbkjstyt:lvo4zphp2wwj@192.53.67.209:5758
fbkjstyt:lvo4zphp2wwj@130.180.231.18:8160
fbkjstyt:lvo4zphp2wwj@192.53.142.239:5936
fbkjstyt:lvo4zphp2wwj@103.130.178.22:5686
fbkjstyt:lvo4zphp2wwj@216.98.254.253:6563
fbkjstyt:lvo4zphp2wwj@192.46.188.237:5896
fbkjstyt:lvo4zphp2wwj@45.56.161.56:8932
fbkjstyt:lvo4zphp2wwj@192.46.201.252:6766
fbkjstyt:lvo4zphp2wwj@45.196.50.62:6384
fbkjstyt:lvo4zphp2wwj@193.160.83.42:6363
fbkjstyt:lvo4zphp2wwj@103.130.178.234:5898
fbkjstyt:lvo4zphp2wwj@72.46.139.62:6622
fbkjstyt:lvo4zphp2wwj@72.46.139.239:6799
fbkjstyt:lvo4zphp2wwj@103.130.178.62:5726
fbkjstyt:lvo4zphp2wwj@72.46.138.21:6247
EOF
# 6. 创建启动脚本
cat > start-proxy-relay.sh << 'EOF'
#!/bin/bash
echo "启动代理中转服务..."
# 杀死之前的进程
pkill -f "gost.*:1000"
# 读取代理列表并启动
i=1
while IFS= read -r line; do
if [ $i -gt 20 ]; then break; fi
port=$((10000 + i))
# 启动 gost 中转
gost -L "socks5://0.0.0.0:$port" -F "socks5://$line" &
echo "端口 $port -> webshare $line"
i=$((i + 1))
sleep 0.1
done < webshare-proxies.txt
echo ""
echo "代理中转已启动!"
echo "Tailscale IP: $(tailscale ip -4)"
echo "监听端口: 10001-10020"
echo ""
echo "在本地使用以下命令连接:"
echo "ssh -L 20001:localhost:10001 -L 20002:localhost:10002 ... user@$(tailscale ip -4)"
echo ""
echo "或使用 gost 本地转发"
wait
EOF
chmod +x start-proxy-relay.sh
# 7. 创建系统服务(可选)
sudo tee /etc/systemd/system/webshare-proxy.service > /dev/null << EOF
[Unit]
Description=Webshare Proxy Relay Service
After=network.target tailscaled.service
[Service]
Type=simple
User=$USER
WorkingDirectory=$HOME/proxy-config
ExecStart=$HOME/proxy-config/start-proxy-relay.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
echo ""
echo "=== 设置完成 ==="
echo "现在运行: ./start-proxy-relay.sh"
echo ""
echo "或者启用系统服务:"
echo "sudo systemctl enable webshare-proxy"
echo "sudo systemctl start webshare-proxy"
echo ""
echo "Tailscale IP: $TAILSCALE_IP"
echo "代理端口: 10001-10020"

0
pr.sh Normal file → Executable file
View File

192
proxy-manager.py Executable file
View File

@ -0,0 +1,192 @@
#!/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()

105
quick-start.sh Normal file
View File

@ -0,0 +1,105 @@
#!/bin/bash
echo "=== Webshare 代理快速启动脚本 ==="
echo ""
# 检查参数
if [ $# -eq 0 ]; then
echo "使用方法:"
echo " $0 <甲骨文Tailscale IP> # 启动代理转发"
echo " $0 test # 测试现有连接"
echo " $0 stop # 停止所有代理"
echo ""
echo "示例:"
echo " $0 100.64.0.1"
exit 1
fi
case "$1" in
"test")
echo "测试代理连接..."
if command -v python3 &> /dev/null; then
python3 -c "
import requests
import concurrent.futures
def test_proxy(port):
try:
proxy = f'socks5://127.0.0.1:{port}'
r = requests.get('http://httpbin.org/ip',
proxies={'http': proxy, 'https': proxy},
timeout=5)
return port, r.json().get('origin', 'Unknown')
except:
return port, None
ports = range(20001, 20006) # 测试前5个
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(test_proxy, ports))
for port, ip in results:
if ip:
print(f'✓ 端口 {port}: {ip}')
else:
print(f'✗ 端口 {port}: 连接失败')
"
else
echo "需要 Python3 来测试代理"
echo "手动测试:"
echo "curl --socks5 127.0.0.1:20001 http://httpbin.org/ip"
fi
;;
"stop")
echo "停止所有代理转发..."
pkill -f "gost.*:2000" 2>/dev/null
pkill -f "proxy-manager.py" 2>/dev/null
echo "已停止"
;;
*)
ORACLE_IP="$1"
echo "甲骨文服务器 IP: $ORACLE_IP"
# 检查 gost
if ! command -v gost &> /dev/null; then
echo "错误: 未找到 gost请先运行 local-client-setup.sh"
exit 1
fi
# 检查 Python 管理器
if [ -f "proxy-manager.py" ] && command -v python3 &> /dev/null; then
echo "使用 Python 管理器启动..."
python3 proxy-manager.py "$ORACLE_IP"
else
echo "使用 shell 脚本启动..."
# 停止旧的进程
pkill -f "gost.*:2000" 2>/dev/null
# 启动转发
echo "启动代理转发..."
for i in {1..20}; do
local_port=$((20000 + i))
oracle_port=$((10000 + i))
gost -L "socks5://127.0.0.1:$local_port" -F "socks5://$ORACLE_IP:$oracle_port" &
echo -n "."
sleep 0.1
done
echo ""
echo "代理转发已启动!"
echo "本地 SOCKS5 代理: 127.0.0.1:20001-20020"
echo ""
echo "测试连接: $0 test"
echo "停止服务: $0 stop"
echo ""
echo "按 Ctrl+C 停止..."
# 等待
trap 'echo "正在停止..."; pkill -f "gost.*:2000"; exit' INT
wait
fi
;;
esac

34
simple-forward.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
# 简化版本:直接在甲骨文服务器上转发 webshare 代理
# 需要先在甲骨文服务器上配置
ORACLE_IP="你的甲骨文Tailscale IP" # 替换为实际IP
# 本地安装 gost
if ! command -v gost &> /dev/null; then
echo "正在安装 gost..."
wget https://github.com/ginuerzh/gost/releases/download/v2.11.5/gost-linux-amd64-2.11.5.gz
gunzip gost-linux-amd64-2.11.5.gz
chmod +x gost-linux-amd64-2.11.5
sudo mv gost-linux-amd64-2.11.5 /usr/local/bin/gost
fi
# 读取 webshare 代理并启动转发
echo "启动代理转发..."
# 示例:将本地 20001-20020 端口转发到甲骨文的 10001-10020 端口
for i in {1..20}; do
local_port=$((20000 + i))
oracle_port=$((10000 + i))
# 启动本地到甲骨文的转发
gost -L "socks5://:${local_port}" -F "socks5://${ORACLE_IP}:${oracle_port}" &
echo "本地端口 ${local_port} -> 甲骨文 ${ORACLE_IP}:${oracle_port}"
done
echo "代理转发已启动,本地 SOCKS5 端口: 20001-20020"
echo "按 Ctrl+C 停止"
wait

70
simple-test.sh Executable file
View File

@ -0,0 +1,70 @@
#!/bin/bash
echo "=== 简单测试 Webshare SOCKS5 代理 ==="
# 代理列表
PROXIES=(
"fbkjstyt:lvo4zphp2wwj@45.196.40.191:6269"
"fbkjstyt:lvo4zphp2wwj@130.180.228.168:6452"
"fbkjstyt:lvo4zphp2wwj@72.1.154.35:7926"
"fbkjstyt:lvo4zphp2wwj@63.141.62.186:6479"
"fbkjstyt:lvo4zphp2wwj@216.170.122.181:6219"
"fbkjstyt:lvo4zphp2wwj@192.53.67.209:5758"
"fbkjstyt:lvo4zphp2wwj@130.180.231.18:8160"
"fbkjstyt:lvo4zphp2wwj@192.53.142.239:5936"
"fbkjstyt:lvo4zphp2wwj@103.130.178.22:5686"
"fbkjstyt:lvo4zphp2wwj@216.98.254.253:6563"
"fbkjstyt:lvo4zphp2wwj@192.46.188.237:5896"
"fbkjstyt:lvo4zphp2wwj@45.56.161.56:8932"
"fbkjstyt:lvo4zphp2wwj@192.46.201.252:6766"
"fbkjstyt:lvo4zphp2wwj@45.196.50.62:6384"
"fbkjstyt:lvo4zphp2wwj@193.160.83.42:6363"
"fbkjstyt:lvo4zphp2wwj@103.130.178.234:5898"
"fbkjstyt:lvo4zphp2wwj@72.46.139.62:6622"
"fbkjstyt:lvo4zphp2wwj@72.46.139.239:6799"
"fbkjstyt:lvo4zphp2wwj@103.130.178.62:5726"
"fbkjstyt:lvo4zphp2wwj@72.46.138.21:6247"
)
WORKING=0
FAILED=0
echo "开始测试 ${#PROXIES[@]} 个代理..."
echo ""
for i in "${!PROXIES[@]}"; do
proxy="${PROXIES[$i]}"
num=$((i + 1))
printf "[%2d] 测试 %s ... " "$num" "${proxy%%@*}@***"
# 使用curl测试代理
result=$(timeout 15 curl -s --socks5 "$proxy" http://httpbin.org/ip 2>/dev/null)
if [ $? -eq 0 ] && echo "$result" | grep -q "origin"; then
ip=$(echo "$result" | grep -o '"origin": "[^"]*"' | cut -d'"' -f4)
echo "$ip"
WORKING=$((WORKING + 1))
else
echo "✗ 连接失败"
FAILED=$((FAILED + 1))
fi
# 避免请求过快
sleep 0.5
done
echo ""
echo "==============================================="
echo "测试完成!"
echo "✓ 工作正常: $WORKING"
echo "✗ 连接失败: $FAILED"
echo "成功率: $(( WORKING * 100 / (WORKING + FAILED) ))%"
if [ $WORKING -gt 0 ]; then
echo ""
echo "建议: 使用工作正常的代理进行中转设置"
else
echo ""
echo "警告: 没有可用的代理,请检查 Webshare 账号状态"
fi

15
start-oracle-proxy.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
# 启动 gost 代理服务器监听20个端口
gost -C oracle-proxy-config.json &
# 或者使用命令行方式启动多个代理
# for port in {10001..10020}; do
# gost -L socks5://:$port &
# done
echo "Oracle proxy servers started on ports 10001-10020"
echo "Tailscale IP: $(tailscale ip -4)"
# 保持脚本运行
wait

179
test-webshare-proxies.py Executable file
View File

@ -0,0 +1,179 @@
#!/usr/bin/env python3
"""
测试 Webshare SOCKS5 代理连通性
"""
import requests
import time
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed
import sys
# 从 proxies_socks5.txt 读取的代理列表
WEBSHARE_PROXIES = [
"socks5://fbkjstyt:lvo4zphp2wwj@45.196.40.191:6269",
"socks5://fbkjstyt:lvo4zphp2wwj@130.180.228.168:6452",
"socks5://fbkjstyt:lvo4zphp2wwj@72.1.154.35:7926",
"socks5://fbkjstyt:lvo4zphp2wwj@63.141.62.186:6479",
"socks5://fbkjstyt:lvo4zphp2wwj@216.170.122.181:6219",
"socks5://fbkjstyt:lvo4zphp2wwj@192.53.67.209:5758",
"socks5://fbkjstyt:lvo4zphp2wwj@130.180.231.18:8160",
"socks5://fbkjstyt:lvo4zphp2wwj@192.53.142.239:5936",
"socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.22:5686",
"socks5://fbkjstyt:lvo4zphp2wwj@216.98.254.253:6563",
"socks5://fbkjstyt:lvo4zphp2wwj@192.46.188.237:5896",
"socks5://fbkjstyt:lvo4zphp2wwj@45.56.161.56:8932",
"socks5://fbkjstyt:lvo4zphp2wwj@192.46.201.252:6766",
"socks5://fbkjstyt:lvo4zphp2wwj@45.196.50.62:6384",
"socks5://fbkjstyt:lvo4zphp2wwj@193.160.83.42:6363",
"socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.234:5898",
"socks5://fbkjstyt:lvo4zphp2wwj@72.46.139.62:6622",
"socks5://fbkjstyt:lvo4zphp2wwj@72.46.139.239:6799",
"socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.62:5726",
"socks5://fbkjstyt:lvo4zphp2wwj@72.46.138.21:6247"
]
def test_single_proxy(index, proxy_url):
"""测试单个代理"""
try:
print(f"[{index+1:2d}] 测试 {proxy_url} ...", end=" ", flush=True)
# 设置代理
proxies = {
'http': proxy_url,
'https': proxy_url
}
# 测试连接
start_time = time.time()
response = requests.get(
'http://httpbin.org/ip',
proxies=proxies,
timeout=15,
verify=False
)
if response.status_code == 200:
data = response.json()
ip = data.get('origin', 'Unknown')
elapsed = time.time() - start_time
print(f"{ip} ({elapsed:.2f}s)")
return index, True, ip, elapsed, None
else:
print(f"✗ HTTP {response.status_code}")
return index, False, None, 0, f"HTTP {response.status_code}"
except requests.exceptions.Timeout:
print("✗ 超时")
return index, False, None, 0, "Timeout"
except requests.exceptions.ProxyError as e:
print(f"✗ 代理错误: {str(e)[:50]}")
return index, False, None, 0, "Proxy Error"
except Exception as e:
print(f"✗ 错误: {str(e)[:50]}")
return index, False, None, 0, str(e)[:50]
def test_all_proxies(max_workers=10):
"""测试所有代理"""
print(f"开始测试 {len(WEBSHARE_PROXIES)} 个 Webshare SOCKS5 代理...")
print("=" * 80)
results = []
working_proxies = []
failed_proxies = []
# 使用线程池并发测试
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交所有任务
futures = {
executor.submit(test_single_proxy, i, proxy): i
for i, proxy in enumerate(WEBSHARE_PROXIES)
}
# 收集结果
for future in as_completed(futures):
try:
result = future.result()
results.append(result)
index, success, ip, elapsed, error = result
if success:
working_proxies.append((index, WEBSHARE_PROXIES[index], ip, elapsed))
else:
failed_proxies.append((index, WEBSHARE_PROXIES[index], error))
except Exception as e:
print(f"任务执行错误: {e}")
# 按索引排序结果
results.sort(key=lambda x: x[0])
working_proxies.sort(key=lambda x: x[0])
failed_proxies.sort(key=lambda x: x[0])
print("=" * 80)
print(f"测试完成!")
print(f"✓ 工作正常: {len(working_proxies)}")
print(f"✗ 连接失败: {len(failed_proxies)}")
if working_proxies:
print(f"\n可用代理列表:")
for index, proxy, ip, elapsed in working_proxies:
print(f" [{index+1:2d}] {ip} ({elapsed:.2f}s) - {proxy}")
if failed_proxies:
print(f"\n失败代理列表:")
for index, proxy, error in failed_proxies:
print(f" [{index+1:2d}] {error} - {proxy}")
# 速度统计
if working_proxies:
speeds = [elapsed for _, _, _, elapsed in working_proxies]
avg_speed = sum(speeds) / len(speeds)
print(f"\n平均响应时间: {avg_speed:.2f}s")
print(f"最快代理: {min(speeds):.2f}s")
print(f"最慢代理: {max(speeds):.2f}s")
return working_proxies, failed_proxies
def test_specific_proxy(index):
"""测试指定索引的代理"""
if 0 <= index < len(WEBSHARE_PROXIES):
result = test_single_proxy(index, WEBSHARE_PROXIES[index])
return result
else:
print(f"错误: 代理索引 {index} 超出范围 (0-{len(WEBSHARE_PROXIES)-1})")
return None
def main():
if len(sys.argv) > 1:
try:
# 测试指定的代理
index = int(sys.argv[1]) - 1 # 用户输入从1开始
print(f"测试第 {sys.argv[1]} 个代理...")
test_specific_proxy(index)
except ValueError:
if sys.argv[1] == "fast":
print("快速测试前5个代理...")
for i in range(min(5, len(WEBSHARE_PROXIES))):
test_single_proxy(i, WEBSHARE_PROXIES[i])
elif sys.argv[1] == "working":
print("只显示工作中的代理...")
working, failed = test_all_proxies()
if working:
print(f"\n生成工作代理列表文件...")
with open('working_proxies.txt', 'w') as f:
for index, proxy, ip, elapsed in working:
f.write(f"{proxy}\n")
print(f"已保存到 working_proxies.txt")
else:
print("使用方法:")
print(" python3 test-webshare-proxies.py # 测试所有代理")
print(" python3 test-webshare-proxies.py 1-20 # 测试指定代理")
print(" python3 test-webshare-proxies.py fast # 快速测试前5个")
print(" python3 test-webshare-proxies.py working # 只保存工作的代理")
else:
# 测试所有代理
test_all_proxies()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,22 @@
# webshare 代理列表示例
# 格式: IP:端口:用户名:密码
proxy1.webshare.io:80:username1:password1
proxy2.webshare.io:80:username2:password2
proxy3.webshare.io:80:username3:password3
proxy4.webshare.io:80:username4:password4
proxy5.webshare.io:80:username5:password5
proxy6.webshare.io:80:username6:password6
proxy7.webshare.io:80:username7:password7
proxy8.webshare.io:80:username8:password8
proxy9.webshare.io:80:username9:password9
proxy10.webshare.io:80:username10:password10
proxy11.webshare.io:80:username11:password11
proxy12.webshare.io:80:username12:password12
proxy13.webshare.io:80:username13:password13
proxy14.webshare.io:80:username14:password14
proxy15.webshare.io:80:username15:password15
proxy16.webshare.io:80:username16:password16
proxy17.webshare.io:80:username17:password17
proxy18.webshare.io:80:username18:password18
proxy19.webshare.io:80:username19:password19
proxy20.webshare.io:80:username20:password20