feat: add subscription auto-sync, node pools, docker deployment docs

This commit is contained in:
root
2026-03-31 06:59:40 +08:00
commit de558019bf
16 changed files with 70598 additions and 0 deletions

239
README.md Normal file
View File

@@ -0,0 +1,239 @@
# 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 # 健康检查间隔(秒),默认 60010分钟
```
## 使用方法
### 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** + FlaskWeb 服务)
- **xray-core**(协议转换引擎)
- **requests[socks]**(健康检查)
- **Docker**(容器化部署)