221 lines
5.9 KiB
Markdown
221 lines
5.9 KiB
Markdown
# INP2P 最终方案 v1(用户网络模型)
|
||
|
||
> 状态:已冻结(按 2026-03-03 讨论结论)
|
||
> 目标:稳定优先,先完成认证/网络模型收敛,再做增量体验优化。
|
||
|
||
---
|
||
|
||
## 0. 冻结决策(已确认)
|
||
|
||
1. 一账号=一网络(1:1)
|
||
2. Hub 离线自动回 Mesh
|
||
3. 改 IP 后:目标节点重连 + 同网广播更新
|
||
4. API Key:保留后台能力,前台不突出
|
||
5. 暂不上 Refresh Token
|
||
6. Node 唯一标识采用 UUID(稳定优先)
|
||
|
||
---
|
||
|
||
## 1. 核心对象模型
|
||
|
||
### 1.1 Account(账号)
|
||
- 控制台登录主体(人)
|
||
- 字段:
|
||
- `account_id` (int64 PK)
|
||
- `username` (unique)
|
||
- `password_hash`
|
||
- `status` (1/0)
|
||
- `created_at`
|
||
|
||
### 1.2 Network(用户网络)
|
||
- 每个账号唯一绑定一个网络
|
||
- 字段:
|
||
- `network_id` (int64 PK)
|
||
- `account_id` (unique FK -> accounts)
|
||
- `cidr` (e.g. `10.0.1.0/24`)
|
||
- `mode` (`mesh`|`hub`)
|
||
- `hub_node_id` (nullable, FK -> nodes.node_id)
|
||
- `fallback_to_mesh` (bool, default true)
|
||
- `status` (1/0)
|
||
- `created_at`, `updated_at`
|
||
|
||
### 1.3 Node(设备)
|
||
- 设备唯一标识不变;展示名可变
|
||
- 字段:
|
||
- `node_id` (UUID, PK) ✅ 后端唯一键
|
||
- `network_id` (FK)
|
||
- `hostname` (设备上报)
|
||
- `alias` (用户自定义昵称,可空)
|
||
- `virtual_ip` (network cidr 内)
|
||
- `node_secret_hash`
|
||
- `relay_enabled` (bool)
|
||
- `online` (bool)
|
||
- `last_seen`
|
||
- `created_at`, `updated_at`
|
||
|
||
### 1.4 凭证对象
|
||
- `session_tokens`(控制台会话,短期)
|
||
- `enroll_tokens`(一次性/短期入网码)
|
||
- `api_keys`(后台自动化,非控制台主要路径)
|
||
|
||
---
|
||
|
||
## 2. 凭证与认证边界(彻底拆分)
|
||
|
||
### 2.1 会话 token(控制台)
|
||
- 登录成功后返回 `session_token`
|
||
- 内含:`account_id`, `network_id`, `role=owner`, `exp`
|
||
- 用于所有控制台 API
|
||
|
||
### 2.2 enroll token(设备入网)
|
||
- 控制台生成,一次性,短时有效(默认 10 分钟)
|
||
- 设备携带 `hostname` + enroll token 兑换 `node_id + node_secret + virtual_ip`
|
||
|
||
### 2.3 node_secret(设备长期)
|
||
- 设备 WS 登录凭证
|
||
- 仅设备连接信令使用,不用于控制台
|
||
|
||
### 2.4 API Key(后台能力)
|
||
- 用于自动化脚本/平台对接
|
||
- 不作为控制台默认登录路径
|
||
- 前台不突出,仅高级设置页可见
|
||
|
||
---
|
||
|
||
## 3. 网络与 IPAM 规则
|
||
|
||
### 3.1 子网分配
|
||
- 池:`10.0.1.0/24` ~ `10.0.254.0/24`
|
||
- 保留:`10.0.0.0/24`、`10.0.255.0/24`
|
||
- 账号注册时分配第一个可用网段
|
||
|
||
### 3.2 地址分配
|
||
- 每网络内自动分配:从 `.2` 开始
|
||
- 保留 `.0/.255/.1`
|
||
- 禁止重复占用
|
||
|
||
### 3.3 手动改 IP
|
||
- 必须在网络 CIDR 内
|
||
- 不可与现有节点冲突
|
||
- 成功后触发:
|
||
1) 目标节点收到 `ip_changed` 推送并重连
|
||
2) 服务端广播 `peer_ip_changed` 给同网在线节点
|
||
|
||
---
|
||
|
||
## 4. 拓扑模式状态机
|
||
|
||
### 4.1 Mesh(默认)
|
||
- 同网节点按策略尝试直连(UDP/TCP)
|
||
- 失败后按中继策略兜底
|
||
|
||
### 4.2 Hub
|
||
- 条件:`hub_node_id` 必填,且必须“在线 + 同网络 + relay_enabled=true”
|
||
- 数据面按 hub 转发
|
||
|
||
### 4.3 Hub 离线回退
|
||
- 监测阈值:15~30 秒无心跳
|
||
- 自动回 `mesh`(记录审计日志)
|
||
- Hub 恢复后暂不自动切回(v1 简化)
|
||
|
||
---
|
||
|
||
## 5. API 草图(v1)
|
||
|
||
## 5.1 认证
|
||
- `POST /api/v1/auth/register`
|
||
- req: `{username,password}`
|
||
- rsp: `{account_id, network:{cidr,mode}}`
|
||
- `POST /api/v1/auth/login`
|
||
- req: `{username,password}`
|
||
- rsp: `{session_token, expires_in, network}`
|
||
- `POST /api/v1/auth/logout`
|
||
|
||
## 5.2 网络配置
|
||
- `GET /api/v1/network`
|
||
- `POST /api/v1/network/mode`
|
||
- req: `{mode:"mesh"|"hub", hub_node_id?}`
|
||
- `POST /api/v1/network/hub`
|
||
- req: `{hub_node_id}`(含在线校验)
|
||
|
||
## 5.3 节点管理
|
||
- `GET /api/v1/nodes`
|
||
- `POST /api/v1/nodes/{node_id}/alias`
|
||
- req: `{alias}`
|
||
- `POST /api/v1/nodes/{node_id}/ip`
|
||
- req: `{virtual_ip}`
|
||
- `POST /api/v1/nodes/{node_id}/kick`
|
||
|
||
## 5.4 入网与设备凭证
|
||
- `POST /api/v1/enroll/create`
|
||
- `POST /api/v1/enroll/revoke/{id}`
|
||
- `POST /api/v1/enroll/consume`
|
||
- req: `{code, hostname}`
|
||
- rsp: `{node_id, node_secret, virtual_ip, network_cidr}`
|
||
|
||
## 5.5 自动化(低显著)
|
||
- `GET/POST /api/v1/settings/api-keys`
|
||
|
||
---
|
||
|
||
## 6. 前端展示规范
|
||
|
||
- 节点主显示名:`alias || hostname`
|
||
- 次级显示:`node_id`(短)
|
||
- 明确区分:
|
||
- "控制台会话"(session)
|
||
- "设备凭证"(node_secret)
|
||
- "自动化凭证"(api key)
|
||
- API Key 页面放到“高级设置”折叠区,不作为主流程入口
|
||
|
||
---
|
||
|
||
## 7. 迁移计划(分阶段)
|
||
|
||
### Phase A(认证收敛,必做)
|
||
1. `auth/login` 改为返回 session token,不再返回 API key
|
||
2. 中间件基于 session 解出 `account_id/network_id`
|
||
3. 控制台 API 全量改用 session 鉴权
|
||
|
||
### Phase B(节点模型升级)
|
||
1. 引入 `node_id(UUID)`
|
||
2. 增加 `alias` 字段
|
||
3. 节点唯一性改以 `node_id` 为准(非 hostname)
|
||
|
||
### Phase C(IPAM + 拓扑闭环)
|
||
1. 改 IP 重连与广播机制
|
||
2. Hub 在线校验 + 自动回 mesh
|
||
3. 观测与审计日志完善
|
||
|
||
---
|
||
|
||
## 8. 验收标准(v1)
|
||
|
||
1. 用户登录后拿到 session token(不是 API key)
|
||
2. 同一网络外的数据不可见
|
||
3. 改 IP 后目标节点重连,其他节点收到变更通知
|
||
4. hub 下线后自动回 mesh
|
||
5. node_id 在重命名 hostname/alias 后仍不变
|
||
6. API Key 不影响控制台主流程
|
||
|
||
---
|
||
|
||
## 9. 风险与规避
|
||
|
||
- 风险:旧 token 体系与新 session 并存期可能混淆
|
||
- 规避:版本开关 + 明确响应字段(`token_type=session`)
|
||
- 风险:节点重连窗口导致短时抖动
|
||
- 规避:变更前提示 + 逐节点串行生效
|
||
- 风险:hub 恢复/掉线频繁导致模式抖动
|
||
- 规避:加入最小驻留时间(如 60s)
|
||
|
||
---
|
||
|
||
## 10. 下一步实施顺序(立即执行)
|
||
|
||
1. 后端:新增 session token 生成/校验(无 refresh)
|
||
2. 后端:中间件切换到 session 识别 network
|
||
3. 前端:登录流程改读 `session_token`
|
||
4. 后端:保留 API key 能力但移出主登录流程
|
||
5. 回归联调:登录、节点、sdwan、connect、enroll、hub 回退
|