Files
frps-manager/README.md
T
Your Name 71214524f4 feat: frps-manager v1.0 - frp 0.70.1 multi-tenant web management system
- Multi-tenant client/proxy management with Flask+SQLite
- Frps server control (start/restart/token rotation)
- Generate frpc.ini with shared server token + admin API
- Dashboard API integration (live client/proxy status)
- RBAC: admin/tenant_admin/user roles
- Audit logging for all operations
- Systemd service files included
- Requires legacy INI format (frp 0.70 TOML auth broken)
2026-08-10 14:17:49 +08:00

204 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# frps-manager
基于 frps 0.70.1 的内网穿透 Web 管理系统,多租户 + Web 端代理规则 CRUD。
## 功能
| 模块 | 说明 |
|------|------|
| 仪表盘 | frps 状态、监听端口、在线客户端/代理数、Server Token 显示、实时在线列表 |
| 租户 | 多租户隔离,每个租户独立带宽/连接配额 |
| 客户端 (frpc) | 注册 frpc 客户端(user 字段 + token),归属租户,启停、旋转 token |
| 代理规则 | 支持 tcp / udp / http / https,配置远端端口、域名、加密压缩、健康检查 |
| frpc.ini 生成 | 点客户端的「frpc.ini」按钮下载一份含所有代理 + 共享 server token + admin API 的配置 |
| 热重载支持 | 生成的 frpc.ini 默认带 `admin_addr`/`admin_port`,修改代理后用户在 frpc 主机执行 `frpc reload -c /etc/frpc.ini` 即可生效(无需 SSH 重启) |
| 用户 | admin / tenant_admin / user 三级 RBAC,每个用户绑定到租户 |
| 审计日志 | 全部管理操作(创建/删除/旋转 token/重载 frps…)写入日志 |
| frps 控制 | 通过 Web 重写 frps.ini 并重启 frps、旋转 server token、查看生成的 frps.ini |
## 关键设计:frps 0.70 的特殊性
**fatedier/frp 0.70.1 的 TOML 配置和 auth 流程有问题**
- TOML 解析器**不接受** `auth.method = "token"` / `auth.token = "..."` 这种点路径键(尽管官方 example 文件这么写)
- `--token` CLI flag 设的值会被 TOML 加载流程覆盖为**空值**
- **唯一真正可用的格式**`legacy INI``[common]` + `token = xxx`),frp 在加载时会打印 `WARNING: ini format is deprecated`
所以本系统:
- 生成 `frps.ini`legacy INI)而不是 frps.toml
- 生成 `frpc.ini`legacy INI)给用户
- 会在 frps 日志看到 deprecation warning — 这是 frp 项目已知问题,未来升级到 0.71+(修复 TOML auth 后)只需把 `render_frps_ini` 改成 TOML 渲染
**另一个特殊性**frps 0.70+ **没有 server-side `[[proxies]]` 段** — 所有代理规则都在 frpc 端 `[[xxx]]` 配置里,启动时通过 control message 推给 frps。所以 Web 系统**所有代理数据都在 frpc.ini 里**frps.ini 只管 bind/dashboard/auth/log。
## 技术栈
- **后端**: Flask 3.0 + Flask-SQLAlchemy + SQLite
- **WSGI**: Gunicorn (2 workers)
- **前端**: Jinja2 模板 + 原生 CSS(无前端框架依赖)
- **被管理**: frps 0.70.1GitHub: fatedier/frp+ frpc 0.70.1
- **认证**: Werkzeug password hashing + Flask session
## 目录结构
```
frps-manager/
├── app.py # Flask 应用主文件(模型、路由、INI 渲染逻辑)
├── wsgi.py # Gunicorn 入口(DB 初始化)
├── init_db.py # 独立 DB 初始化脚本
├── requirements.txt
├── README.md
├── _smoke_test.py # 端到端测试(起 frps + frpc + reload 验证)
├── scripts/
│ ├── deploy.sh # 一键部署脚本(systemd
│ └── dev.sh # 本地开发启动
├── templates/ # Jinja2 模板
│ ├── base.html # 布局 + 导航
│ ├── login.html
│ ├── dashboard.html
│ ├── tenants.html / tenant_form.html
│ ├── clients.html / client_form.html
│ ├── proxies.html / proxy_form.html
│ ├── users.html / user_form.html
│ ├── logs.html
│ ├── change_password.html
│ └── error.html
├── static/
│ └── style.css # 全部样式
├── instance/ # SQLite DB + server token(运行时生成)
│ ├── frps_manager.db
│ └── server_token # 0600 权限,仅 root 可读
└── runtime/ # 运行时数据
├── bin/frps # frps 二进制(deploy.sh 自动下载)
├── conf/frps.ini # 由 app.py 生成的 frps 配置
├── logs/ # gunicorn / frps 日志
├── frps.service # frps systemd 单元
├── frps-manager.service # web systemd 单元
└── frpc@.service # 用户给 frpc 主机用的模板
```
## 安装
### 一键部署(推荐)
```bash
git clone <repo-url> /opt/frps-manager
cd /opt/frps-manager
sudo bash scripts/deploy.sh
```
部署脚本会自动:
1. 安装系统依赖(python3, pip, venv, curl
2. 下载 frp 0.70.1 二进制到 `runtime/bin/frps`
3. 创建 venv 并安装依赖
4. 初始化 SQLite(默认管理员 `admin / admin`,默认租户 `default`
5. 生成 `frps.ini`(含自动生成的 server token
6. 安装并启动两个 systemd 服务:
- `frps.service` — 监听 0.0.0.0:7000dashboard 在 127.0.0.1:7500
- `frps-manager.service` — Web UI 在 0.0.0.0:5390
启动后访问 `http://<host>:5390`,用 `admin / admin` 登录,**立刻去「改密」改掉默认密码**。
### 本地开发
```bash
cd frps-manager
bash scripts/dev.sh
# 浏览器打开 http://localhost:5390
```
## 多租户使用流程
1. **管理员**登录 → 创建 **租户**(带带宽/连接配额元数据,文档用)
2. 创建 **普通用户**(绑定到该租户,role = user
3. 租户用户登录 → 创建 **frpc 客户端**(分配名称 + 租户)
4. 在该客户端下添加 **代理规则**(类型、远端端口/域名、本地端口、加密/压缩/健康检查…)
5. 点客户端列表的「frpc.ini」下载配置(包含所有代理 + 共享 server token + admin API
6.`frpc.ini` 拷贝到 frpc 主机,启动 frpc
7. **改代理后**:用户拉到新 frpc.ini 后在 frpc 主机执行 `frpc reload -c /etc/frpc.ini`frpc 自动应用新配置(dashboard 立刻显示新代理在线)
## frpc 配置示例
Web 生成的 frpc.ini
```ini
# Generated by frps-manager for client: laptop-jdoe
[common]
server_addr = your.frps.host
server_port = 7000
authentication_method = token
token = AbCdEf123456... # 与所有 frpc 共用的 server token
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin # 用于 `frpc reload` 命令
[laptop-jdoe_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6001
use_encryption = true
[laptop-jdoe_web]
type = http
local_ip = 127.0.0.1
local_port = 8080
custom_domains = web.example.com
```
存到 frpc 主机 `/etc/frpc/laptop-jdoe.ini`,然后用模板 unit
```bash
sudo cp /path/to/frps-manager/runtime/frpc@.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now frpc@laptop-jdoe
```
改代理后:
```bash
# 在 frpc 主机执行
sudo frpc reload -c /etc/frpc/laptop-jdoe.ini
# 或者 frpc reload -c /etc/frpc.ini(按你保存的路径)
```
## 配置(环境变量)
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `FLASK_SECRET` | 随机 | Flask session 密钥(生产必须设置一个长随机串) |
| `FRPS_BIN` | `runtime/bin/frps` | frps 可执行文件路径 |
| `FRPS_CONFIG` | `runtime/conf/frps.ini` | frps.ini 路径 |
| `FRPS_SERVICE` | `frps` | systemd 单元名(不含 .service |
| `FRPS_DASHBOARD_URL` | `http://127.0.0.1:7500` | frps dashboard URL |
| `FRPS_DASHBOARD_USER` | `admin` | dashboard 用户名 |
| `FRPS_DASHBOARD_PASS` | `admin123` | dashboard 密码 |
| `FRPS_BIND_PORT` | `7000` | frps 监听端口 |
| `FRPS_WEB_ADDR` | `127.0.0.1` | dashboard 监听地址 |
| `FRPS_WEB_PORT` | `7500` | dashboard 端口 |
| `FRPS_VHOST_HTTP_PORT` | `80` | http 虚拟主机端口 |
| `FRPS_VHOST_HTTPS_PORT` | `443` | https 虚拟主机端口 |
| `FRPC_ADMIN_ADDR` | `127.0.0.1` | 写入 frpc.ini 的 admin API 地址 |
| `FRPC_ADMIN_PORT` | `7400` | 写入 frpc.ini 的 admin API 端口(每台 frpc 主机必须唯一) |
| `FRPC_ADMIN_USER` | `admin` | 写入 frpc.ini 的 admin 用户名 |
| `FRPC_ADMIN_PWD` | `admin` | 写入 frpc.ini 的 admin 密码 |
## 安全建议
- 改默认 admin 密码
- dashboard7500)只在 127.0.0.1 监听 — 如果要让远程看 dashboard,把它放到 nginx 反向代理后面 + HTTPS
- Web UI5390)同理,建议放到 nginx + HTTPS 后
- 不要把 frps 暴露到公网 0.0.0.0:7000 而不设防火墙 — **每个 frpc 用同一个 server token**,谁拿到 token 都能连
- 如果需要更强的隔离,部署多个 frps 实例在不同端口,每个 frps 一个 server token
- `instance/server_token` 包含所有 frpc 的共享密钥,备份时加密
## 已知限制
- frps 0.70.1 INI 格式被官方 deprecation warning — 升级到 0.71+ 后只需把 `render_frps_ini` 改为 TOML
- frpc 0.70.1 也用 INIfrpc 端 INI 一直支持到最新版本,不受影响)
- Web UI 不支持批量操作(一次性添加多个代理)
- 没有内嵌 traffic chart;如需图表请用 Prometheus + frps 自带的 `/metrics` 端点
## License
MIT