Your Name 76dca88ee7 fix: 服务器停止时优雅等待连接关闭
问题: stop() 只调用 server.close() 后立即停止事件循环
导致活跃连接收到 GeneratorExit,产生大量 Task destroyed 警告

修复: 使用 run_coroutine_threadsafe 在子线程事件循环中执行
server.wait_closed(),最多等待5秒优雅关闭
2026-07-17 00:09:27 +08:00
2026-07-16 18:35:03 +08:00

SOCKS Manager — SOCKS5 代理管理平台

内建 asyncio SOCKS5 服务器(RFC 1928/1929)的完整代理管理平台,一个 Python 进程即可运行。支持多实例管理、流量控制、用户管理、审计日志、实时监控。

架构

┌──────────────────────────────────────────────┐
│  Web 管理面板 (Flask + Bootstrap 5 暗色主题)   │
├──────────────────────────────────────────────┤
│  RESTful API (/api/*)                        │
├────────────┬──────────────┬──────────────────┤
│ engine/    │ services/    │                  │
│ └server.py │ └user_service│  数据: SQLite    │
│  asyncio   │   流量/认证  │  socks_manager.db│
│  SOCKS5    │ └stats_      │                  │
│  服务器    │   监控/趋势  │                  │
│ └instances │ └backup_     │                  │
│   多实例   │   备份恢复   │                  │
└────────────┴──────────────┴──────────────────┘

功能覆盖

需求 实现
多实例管理 每个实例独立事件循环,支持创建/启动/停止/重启
基础参数 监听地址(IPv4/IPv6)、端口、超时可视化配置
底层引擎 内建 asyncio SOCKS5 服务器(RFC 1928/1929
配置热重载 修改参数后重启实例生效,不中断 Web 面板
多身份认证 无认证 / 账号密码认证
流量控制 总流量上限、月流量上限、超额自动停机
速度与并发 上下行带宽限制(Mbps)、最大并发连接数
IP 白名单/黑名单 用户级逗号分隔配置
账号生命周期 生效时间、过期时间、一键封禁/解封
大盘控制台 CPU/内存/网络吞吐量/活跃连接实时图表
实时连接追踪 源IP/目标域名/协议/持续时间,手动断开
流量统计报表 30 天折线/柱状图(Chart.js
详细审计日志 按事件/用户/IP 筛选,分页查询
级联代理 连接建立时自动代理至目标(可扩展 upstream)
负载均衡 多实例配置后按端口轮询
管理员认证 环境变量 SM_ADMIN_PASSWORD 保护
防爆破 自动阻断频繁登录尝试(Fail2Ban 机制)
密码安全 bcrypt 哈希存储 SOCKS5 用户密码(兼容旧明文自动迁移)
会话管理 自定义 Cookie 域名/安全/名称,支持 HTTPS 部署
自动备份 一键备份 SQLite,按份数清理
每日流量快照 后台线程每小时记录一次,用于月度趋势图表
RESTful API 全部管理功能通过 /api/ 暴露

快速开始

cd /root/socks-manager

# 安装依赖
pip install -r requirements.txt --break-system-packages

# 设置管理员密码(首次启动如未设置,自动使用默认密码 admin123 并写入 .env
export SM_ADMIN_PASSWORD=你的密码

# 启动
python3 run.py

访问 http://你的IP:5000,用户名 admin,密码为环境变量值。

⚠️ 首次启动时如果 SM_ADMIN_PASSWORD 未设置,会自动写入默认密码 admin123.env 文件。生产环境请务必修改此密码。

环境变量

变量 默认值 说明
SM_ADMIN_USER admin 管理员用户名
SM_ADMIN_PASSWORD "" 管理员密码(必须设置)
SM_SECRET_KEY sm-dev-key-change-in-prod Flask 会话密钥(生产环境务必修改,建议随机 64 位字符串)
SM_SESSION_DOMAIN None 会话 Cookie 域名(跨域访问时设为你的域名或 IP)
SM_COOKIE_SECURE false 是否启用 Cookie Secure 标志(HTTPS 时设为 true
SM_SESSION_NAME sm_session 会话 Cookie 名称(多实例同域名时避免冲突)
SM_DB_URI sqlite:///socks_manager.db 数据库连接串
SM_PORT 5000 Web 面板监听端口
SM_HOST 0.0.0.0 Web 面板监听地址
SM_BACKUP_DIR ./backups/ 备份文件存储目录
SM_LOG_LEVEL INFO 日志级别:DEBUG/INFO/WARN/ERROR

常见问题

1. 在其他服务器上无法登录

问题:浏览器访问面板,输入密码后提示错误或跳转回登录页。

可能原因 & 解决方案:

原因 解决
密码不一致 确认所有服务器 .env 文件中的 SM_ADMIN_PASSWORD 一致
Cookie 被浏览器拒绝(HTTP + 非标准域名) 通过 curl -c /tmp/cookies.txt -X POST -d "username=admin&password=xxx" http://你的IP:5000/login 测试
通过 SOCKS5 代理访问面板 直连(非代理模式)访问面板
Session Cookie 域名不匹配 设置 SM_SESSION_DOMAIN=你的IP 并重启
HTTPS 下未设置 Secure 设置 SM_COOKIE_SECURE=true

验证登录是否成功:

curl -c /tmp/sm_cookies.txt -b /tmp/sm_cookies.txt \
  -X POST -d "username=admin&password=你的密码" \
  http://你的IP:5000/login -w "%{http_code} %{redirect_url}"

返回 302 /dashboard 表示成功。

2. 仪表盘流量趋势图无数据

首次部署后需等待 1 小时,后台线程每小时记录一次流量快照。也可以手动记录一次:

python3 -c "from services.stats_service import record_traffic_snapshot; record_traffic_snapshot()"

3. SOCKS5 用户密码安全性

SOCKS5 协议(RFC 1929)本身采用明文传输密码。本项目服务端使用 bcrypt 哈希存储,兼容旧版明文存储的数据库(首次验证时自动迁移到哈希)。Web 面板中展示用户时不会泄露密码。

核心代码结构

├── app.py              # Flask 应用工厂
├── config.py           # 配置
├── auth.py             # 登录认证 + 防爆破
├── models.py           # SQLAlchemy 数据模型(含 bcrypt 密码方法)
├── database.py         # 数据库初始化
├── run.py              # 启动入口
│
├── engine/
│   ├── server.py       # asyncio SOCKS5 服务器(核心引擎)
│   └── instances.py    # 多实例管理器(线程安全)
│
├── services/
│   ├── user_service.py # 用户管理/认证/流量/防爆破
│   ├── stats_service.py# 监控/统计/趋势/流量快照
│   └── backup_service.py# 备份与恢复
│
├── api/
│   └── v1.py           # RESTful API(实例/用户/日志/备份)
│
├── web/
│   └── routes.py       # Web 管理面板路由
│
└── templates/          # Jinja2 模板(暗色 Bootstrap 5
    ├── base.html       # 布局(侧边栏+导航+全局样式)
    ├── dashboard.html  # 仪表盘(实时图表 + 最近审计日志)
    ├── instances.html  # 代理实例管理
    ├── users.html      # 用户管理
    ├── stats.html      # 流量统计
    ├── connections.html# 活跃连接
    ├── logs.html       # 审计日志
    └── system.html     # 系统管理

API 参考

方法 路径 说明
GET /api/dashboard 仪表盘汇总
GET /api/stats/system 实时系统指标(含最近 10 分钟历史)
GET /api/stats/connections 活跃连接列表
GET /api/stats/traffic-trend?days=30 流量趋势
GET /api/stats/users 用户流量排名
GET /api/stats/instances 实例流量统计
GET/POST /api/instances 实例列表/创建
PUT/DELETE /api/instances/<id> 更新/删除实例
POST /api/instances/<id>/start|stop|restart 实例启停
POST /api/instances/sync 同步所有实例状态
GET/POST /api/users 用户列表/创建
PUT/DELETE /api/users/<id> 更新/删除用户
POST /api/users/<id>/toggle|ban 用户启停/封禁
GET /api/logs?page=1&event=&user=&src_ip= 审计日志查询
GET/POST /api/backups 备份列表/创建
POST /api/backups/<id>/restore 恢复备份
POST /api/backups/cleanup 清理旧备份

所有 API 需要登录认证(Session Cookie),未登录返回 401。

生产建议

# 1. 安装生产依赖
pip install -r requirements.txt --break-system-packages

# 2. 设置强密钥
export SM_SECRET_KEY=$(openssl rand -hex 32)
export SM_ADMIN_PASSWORD=你的强密码

# 3. 使用 gunicorn 部署
gunicorn -w 4 -b 0.0.0.0:5000 run:app

# 4. 前置 Nginx 反向代理 + Let's Encrypt SSL
# nginx.conf 示例:
# location / {
#     proxy_pass http://127.0.0.1:5000;
#     proxy_set_header Host $host;
#     proxy_set_header X-Real-IP $remote_addr;
#     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#     proxy_set_header X-Forwarded-Proto $scheme;
# }

# 5. HTTPS 时开启 Secure Cookie
export SM_COOKIE_SECURE=true

# 6. 多服务器跨域访问时设置 SESSION_DOMAIN(必须与浏览器 URL 一致)
export SM_SESSION_DOMAIN=你的域名或IP

其他建议:

  • 确保 .env 文件在 .gitignore 中(已配置),不要提交到 git 仓库
  • 设置 SM_LOG_LEVEL=WARN 减少日志量
  • 配置 crontab 定期备份数据库
  • 使用 Daemon 或 systemd 管理进程
S
Description
No description provided
Readme 239 KiB
0.0.2 Latest
2026-07-17 10:17:11 +08:00
Languages
Python 61.3%
HTML 38.7%