240 lines
7.8 KiB
Markdown
240 lines
7.8 KiB
Markdown
# AirToSocks
|
||
|
||
将 vmess / vless / trojan / ss 代理订阅链接批量转换为可用的 SOCKS5 代理,并提供 Web 管理界面和随机获取 API。
|
||
|
||
## 原理
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ AirToSocks 系统 │
|
||
│ │
|
||
│ 订阅地址 ──► 解析订阅内容 ──► 导入节点列表 │
|
||
│ │ │
|
||
│ 定时健康检查 │
|
||
│ (每10分钟并发检测) │
|
||
│ │ │
|
||
│ ┌──────────┴──────────┐ │
|
||
│ ▼ ▼ │
|
||
│ xray-core A xray-core B │
|
||
│ (本地 SOCKS5 端口) (本地 SOCKS5 端口) │
|
||
│ :10001 ~ :11000 :10001 ~ :11000 │
|
||
│ │ │ │
|
||
│ └──────────┬──────────┘ │
|
||
│ ▼ │
|
||
│ /api/random │
|
||
│ 随机返回可用 SOCKS5 │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**核心流程:**
|
||
|
||
1. **订阅解析**:通过订阅地址获取代理链接(base64 编码或明文),解析为节点对象
|
||
2. **协议转换**:为每个节点启动独立的 xray-core 进程,将 vmess/vless/trojan/ss 协议转换为本地 SOCKS5 代理
|
||
3. **健康检查**:并发通过 SOCKS5 代理访问 `ifconfig.me/ip`,验证代理可用性并获取出口 IP
|
||
4. **随机返回**:通过 API 随机返回一个经过验证的可用 SOCKS5 代理地址
|
||
|
||
**每个节点对应一个独立的 xray-core 进程,监听在不同端口(10001-11000),互不干扰。**
|
||
|
||
## 功能特性
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 订阅管理 | 添加订阅地址,自动同步节点,支持定时自动更新 |
|
||
| 协议支持 | vmess / vless / trojan / ss |
|
||
| 健康检查 | 并发 20 线程检测,32 节点约 10 秒完成 |
|
||
| 自定义节点池 | 关键字搜索节点,组合创建专属节点池 |
|
||
| 随机 API | 全局随机 / 池内随机,返回前验证端口存活 |
|
||
| Web 管理 | 一站式管理页面,可视化操作 |
|
||
|
||
## 部署
|
||
|
||
### 方式一:Docker Compose(推荐)
|
||
|
||
```bash
|
||
# 克隆项目
|
||
git clone <repo-url> airtosocks
|
||
cd airtosocks
|
||
|
||
# 启动
|
||
docker-compose up -d
|
||
|
||
# 查看日志
|
||
docker-compose logs -f
|
||
|
||
# 停止
|
||
docker-compose down
|
||
```
|
||
|
||
服务启动后访问 `http://<your-ip>:8080`
|
||
|
||
### 方式二:直接运行
|
||
|
||
```bash
|
||
# 环境要求:Python 3.10+
|
||
cd airtosocks
|
||
|
||
# 创建虚拟环境
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
|
||
# 安装依赖
|
||
pip install -r requirements.txt
|
||
|
||
# 启动
|
||
python main.py
|
||
|
||
# 或使用启动脚本
|
||
chmod +x start.sh
|
||
./start.sh
|
||
```
|
||
|
||
### 方式三:后台运行
|
||
|
||
```bash
|
||
source venv/bin/activate
|
||
nohup python main.py &> data/server.log &
|
||
```
|
||
|
||
### 配置文件
|
||
|
||
创建 `config.yaml` 可自定义参数:
|
||
|
||
```yaml
|
||
port: 8080 # Web 服务端口
|
||
check_interval: 600 # 健康检查间隔(秒),默认 600(10分钟)
|
||
```
|
||
|
||
## 使用方法
|
||
|
||
### 1. 导入订阅
|
||
|
||
打开 Web 页面,在「订阅管理」板块:
|
||
|
||
1. 输入订阅名称(可选)
|
||
2. 粘贴订阅地址
|
||
3. 选择自动更新频率(不更新 / 每1小时 / 每2小时 / 每6小时 / 每12小时 / 每24小时)
|
||
4. 点击「添加订阅」
|
||
|
||
支持的订阅格式:
|
||
- base64 编码的多行链接
|
||
- 明文多行链接(每行一个)
|
||
- 自动识别 vmess / vless / trojan / ss 协议
|
||
|
||
### 2. 手动导入链接
|
||
|
||
在「导入代理链接」板块,直接粘贴代理链接(每行一个),点击「添加链接」。
|
||
|
||
### 3. 健康检查
|
||
|
||
- **自动检查**:每 10 分钟自动检测所有节点
|
||
- **手动检查**:点击「检查全部」按钮立即检测
|
||
|
||
检查通过的节点标记为可用(绿色),未通过的标记为不可用(红色)。
|
||
|
||
### 4. 创建节点池
|
||
|
||
在「自定义节点池」板块:
|
||
|
||
1. 输入关键字(如 `香港`),点击「搜索」
|
||
2. 勾选需要的节点
|
||
3. 输入新的关键字(如 `日本`),点击「搜索」,之前的选择保留
|
||
4. 继续搜索并勾选更多节点
|
||
5. 输入池名称,点击「创建节点池」
|
||
|
||
### 5. 获取 SOCKS5 代理
|
||
|
||
**全局随机:**
|
||
```bash
|
||
curl http://<your-ip>:8080/api/random
|
||
```
|
||
|
||
**节点池随机:**
|
||
```bash
|
||
curl http://<your-ip>:8080/api/pools/<pool_id>/random
|
||
```
|
||
|
||
返回示例:
|
||
```json
|
||
{
|
||
"protocol": "socks5",
|
||
"host": "64.81.114.33",
|
||
"port": 10234,
|
||
"url": "socks5://64.81.114.33:10234",
|
||
"available": true,
|
||
"last_check": "2026-03-30T22:00:00",
|
||
"source": {
|
||
"name": "香港 01 | 高级专线",
|
||
"protocol": "vless",
|
||
"address": "hk1.example.com",
|
||
"port": 443
|
||
}
|
||
}
|
||
```
|
||
|
||
## API 接口
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| `GET` | `/api/random` | 全局随机获取 SOCKS5 |
|
||
| `GET` | `/api/random/info` | 随机获取(纯文本格式) |
|
||
| `GET` | `/api/links` | 获取所有节点列表 |
|
||
| `POST` | `/api/links` | 批量添加链接 `{"links": ["vmess://..."]}` |
|
||
| `DELETE` | `/api/links/<node_id>` | 删除节点 |
|
||
| `POST` | `/api/check` | 检查所有节点 |
|
||
| `POST` | `/api/check/<node_id>` | 检查单个节点 |
|
||
| `GET` | `/api/subscriptions` | 获取订阅列表 |
|
||
| `POST` | `/api/subscriptions` | 添加订阅 `{"name":"xx","url":"...","sync_interval":120}` |
|
||
| `POST` | `/api/subscriptions/<id>/sync` | 手动同步订阅 |
|
||
| `DELETE` | `/api/subscriptions/<id>` | 删除订阅及关联节点 |
|
||
| `GET` | `/api/nodes/search?q=<keyword>` | 按关键字搜索节点 |
|
||
| `GET` | `/api/pools` | 获取所有节点池 |
|
||
| `POST` | `/api/pools` | 创建节点池 `{"name":"xx","node_ids":["..."]}` |
|
||
| `PUT` | `/api/pools/<id>` | 更新节点池 |
|
||
| `DELETE` | `/api/pools/<id>` | 删除节点池 |
|
||
| `GET` | `/api/pools/<id>/random` | 从指定池随机获取 SOCKS5 |
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
airtosocks/
|
||
├── main.py # 主程序
|
||
├── requirements.txt # Python 依赖
|
||
├── start.sh # 启动脚本
|
||
├── config.yaml.example # 配置文件示例
|
||
├── Dockerfile # Docker 镜像定义
|
||
├── docker-compose.yml # Docker Compose 编排
|
||
├── config/ # 配置数据
|
||
│ ├── proxies.json # 节点数据
|
||
│ ├── subscriptions.json # 订阅数据
|
||
│ └── pools.json # 节点池数据
|
||
├── data/ # 运行数据
|
||
│ └── xray_*.json # xray 配置文件
|
||
└── bin/ # xray-core 二进制(自动下载)
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
**Q: 代理全部显示不可用?**
|
||
- 检查服务器网络是否能访问目标代理服务器
|
||
- 部分代理可能需要特定的 TLS/SNI 配置
|
||
- 查看 `data/server.log` 日志排查具体错误
|
||
|
||
**Q: Docker 部署后无法访问?**
|
||
- 确认端口映射正确:`-p 8080:8080`
|
||
- 检查防火墙是否放行端口
|
||
|
||
**Q: 如何修改检查间隔?**
|
||
- 创建 `config.yaml`,设置 `check_interval: 600`(秒)
|
||
- 重启服务生效
|
||
|
||
**Q: SOCKS5 代理绑定在哪个地址?**
|
||
- 默认绑定 `0.0.0.0`,可通过服务器公网 IP 直接访问
|
||
- 随机 API 返回的 host 是当前请求的主机地址
|
||
|
||
## 技术栈
|
||
|
||
- **Python 3** + Flask(Web 服务)
|
||
- **xray-core**(协议转换引擎)
|
||
- **requests[socks]**(健康检查)
|
||
- **Docker**(容器化部署)
|