# 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/` 暴露 | ## 快速开始 ```bash 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` | 验证登录是否成功: ```bash 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 小时,后台线程每小时记录一次流量快照。也可以手动记录一次: ```bash 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/` | 更新/删除实例 | | POST | `/api/instances//start\|stop\|restart` | 实例启停 | | POST | `/api/instances/sync` | 同步所有实例状态 | | GET/POST | `/api/users` | 用户列表/创建 | | PUT/DELETE | `/api/users/` | 更新/删除用户 | | POST | `/api/users//toggle\|ban` | 用户启停/封禁 | | GET | `/api/logs?page=1&event=&user=&src_ip=` | 审计日志查询 | | GET/POST | `/api/backups` | 备份列表/创建 | | POST | `/api/backups//restore` | 恢复备份 | | POST | `/api/backups/cleanup` | 清理旧备份 | 所有 API 需要登录认证(Session Cookie),未登录返回 401。 ## 生产部署 ### 1. WSGI 生产服务器(Gunicorn) Flask 内置开发服务器不适合生产环境。使用 **Gunicorn**(生产级 WSGI 服务器): ```bash # 安装 gunicorn pip install gunicorn --break-system-packages # 启动(4 worker 进程,适合 4 核服务器) gunicorn -w 4 -b 0.0.0.0:5000 --timeout 120 run:app # 推荐参数(更长超时 + 优雅关闭) gunicorn -w 2 -b 0.0.0.0:5000 \ --timeout 300 \ --graceful-timeout 30 \ --max-requests 10000 \ --max-requests-jitter 1000 \ run:app ``` > **注意**:SOCKS5 代理实例运行在独立的 asyncio 线程中,不受 Gunicorn worker 数量影响。 --- ### 2. Systemd 服务配置(推荐) 创建 `/etc/systemd/system/socks-manager.service`: ```ini [Unit] Description=SOCKS5 Proxy Manager After=network.target [Service] Type=notify User=root WorkingDirectory=/opt/socks-manager Environment="PATH=/usr/local/bin:/usr/bin:/bin" # 生产环境变量(按需修改) Environment="SM_ADMIN_PASSWORD=你的强密码" Environment="SM_SECRET_KEY=生产环境用openssl rand -hex 32生成" Environment="SM_LOG_LEVEL=WARN" # Environment="SM_COOKIE_SECURE=true" # HTTPS 时开启 # Environment="SM_SESSION_DOMAIN=你的域名或IP" # 跨域时设置 ExecStart=/usr/local/bin/gunicorn -w 2 -b 0.0.0.0:5000 \ --timeout 300 \ --graceful-timeout 30 \ run:app # 优雅关闭:先给 SOCKS5 实例时间关闭活跃连接 ExecStop=/bin/kill -s TERM $MAINPID TimeoutStopSec=60 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` 启动服务: ```bash systemctl daemon-reload systemctl enable --now socks-manager systemctl status socks-manager journalctl -u socks-manager -f # 查看实时日志 ``` --- ### 3. Nginx 反向代理 + SSL ```nginx server { listen 80; server_name 你的域名; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name 你的域名; ssl_certificate /etc/letsencrypt/live/你的域名/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/你的域名/privkey.pem; 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; proxy_buffering off; proxy_request_buffering off; proxy_http_version 1.1; } } ``` --- ### 4. 生产环境检查清单 ✅ **强制修改默认密码** ```bash # 生成强密钥 export SM_SECRET_KEY=$(openssl rand -hex 32) ``` ✅ **数据库备份** - 配置 crontab 每日备份 `socks_manager.db` - 定期测试恢复流程 ✅ **日志级别** - 生产环境设置 `SM_LOG_LEVEL=WARN` 减少日志量 ✅ **HTTPS** - 启用 Let's Encrypt SSL 证书 - 设置 `SM_COOKIE_SECURE=true` ✅ **防火墙** - 只开放需要的端口:Web 面板(5000) + SOCKS5 代理端口 - SOCKS5 端口建议限制源 IP ✅ **优雅关闭** - v1.1+ 版本已修复 SOCKS5 实例的优雅关闭逻辑 - 停止服务时最多等待 5 秒让活跃连接正常关闭 - 避免 `GeneratorExit` 和 `Task was destroyed` 警告