This commit is contained in:
parent
fc791e1d61
commit
169196a372
|
|
@ -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.
|
||||||
|
|
@ -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`
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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,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"
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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": []
|
||||||
|
}
|
||||||
|
|
@ -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,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()
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue