64 lines
7.5 KiB
Markdown
64 lines
7.5 KiB
Markdown
# SDD-004:客户端企业入口与线路选择
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| 版本 / 级别 | 0.2 / S3(客户端交互、认证配置安全边界与列表展示) |
|
||
| 设计状态 | 实施中 |
|
||
| 实现状态 | 客户端企业入口、能力读取、路由标签、实测隧道探测与信号格、WireGuard 认证配置边界和专线列表已实现;WireGuard 浏览器 OIDC 仍未实现 |
|
||
| 日期 | 2026-10-21 |
|
||
| 关联需求 | 企业选择、飞书登录入口、模式和节点延迟;WireGuard 认证方式与专线列表操作 |
|
||
| 批准状态 | 用户提供竞品截图并要求按现有项目继续实现 |
|
||
|
||
## 1. 背景、目标与范围
|
||
|
||
- 当前 `client/src/App.tsx` 只有服务端地址和密码表单、线路平铺列表。`backend/internal/api/api.go` 的匿名 `/api/client/capabilities` 返回 `oidc: false`;OpenVPN 的 `openvpn-auth-oauth2` 与 WireGuard 客户端会话互不兼容。`backend/internal/api/client.go` 的线路含 `endpoint`,不含节点 RTT;`client_probe` 是经 WireGuard 到固定公网 TCP 目标的诊断。
|
||
- 目标:以 OpsX 自己的品牌做企业入口、认证选择和节点选择弹窗;用户配置的服务器才是“单位”,不预填竞品单位。只给实测线路显示延迟/颜色和信号格。
|
||
- 本次不新增身份映射、全局路由覆盖或系统 DNS 修改。登录方式与网络模式必须与真实服务端/本机能力一致。保留已有 HTTP 地址支持、密码/MFA 登录、登录会话、设备私钥和连接状态语义。
|
||
|
||
## 2. 需求与约束
|
||
|
||
- FR-01:登录页标为“选择接入点”,填写服务端地址并自动带入上次使用的地址;验证真实 `/api/health` 后进入认证界面。切换接入点清除账号口令,不显示历史地址下拉。
|
||
- FR-02:根据服务端 `/api/client/capabilities` 的 `password/oidc` 能力决定展示入口;`password:false` 不呈现密码表单,`oidc:false` 不呈现飞书入口。`oidc:true` 但客户端浏览器回调未实现时明确禁用,不重定向到 OpenVPN 回调;两者均不可用时提示管理员。未来开启浏览器登录须实现授权码+PKCE、回调一次性交换与稳定 `issuer/sub` 绑定 VPNUser,禁止按邮箱自动授予线路。
|
||
- FR-03:线路选择展示服务端真实授权线路;极速/全局用线路下发的路由策略判断。未有可切换策略时模式只是当前策略标记,不保存虚构偏好或擅自修改 AllowedIPs。
|
||
- FR-04:延迟数据必须来自对应线路的实际 Go WireGuard 探针。探测失败/未登记设备时显示不可测,不得用控制面健康请求替代节点 RTT;阈值只用于实测后的色彩映射。
|
||
- NFR-01:无效授权与离线不应误报已登录、已连接或高质量节点;浏览器预览不调用原生接口。
|
||
- FR-05:WireGuard 创建和编辑页展示认证方式:现有“客户端账号 + 设备密钥”可选;第三方 OAuth2/OIDC 显示接入说明且不可选。服务端对显式提交未知模式或 oidc 拒绝保存;旧配置无字段保持原行为。静态 Peer 的已有密钥能力不受此选项保护,页面应如实提示。
|
||
- FR-06:专线列表和详情显示认证方式;列表启动/停止按钮固定可见,并依据实际运行状态切换;其他协议不臆测认证类型。
|
||
|
||
## 3. 架构与方案
|
||
|
||
前端负责向导和显示;Rust 验证服务端地址、取得 `password/oidc` 能力并调用当前已有的客户端 API;Go 组件执行真实 TCP 出口探测。按用户选择的运行中线路拨号,后端继续按 `VPNUser` 授权隔离。节点列表使用现有 `/api/client/lines`,不造地理位置/服务器名称。OpenVPN OIDC 配置不作为客户端 OIDC 能力来源。
|
||
|
||
## 4. 接口、数据与配置契约
|
||
|
||
- 匿名 `/api/client/capabilities` 既有 `password/oidc/wireguard` 布尔值;可选 `oidc_provider` 用于将飞书/Lark 与其他 OIDC 提供商区分,旧服务端缺字段按普通“第三方认证”显示。`oidc:false` 时隐藏第三方认证入口,`password:false` 时隐藏密码表单;老服务端返回 HTML 则不进入登录步骤。
|
||
- `client_probe` 在原结果基础上增加本次成功连接耗时 `latency_ms`(含隧道启动与握手);未成功时不提供延迟。前端只为对应线路显示该值,重新选择单位或重新登录后清除。可选 `latency_probe` 为 VPN 路由内的 IP:端口;未配置时用 `223.5.5.5:443`。线路接口增加由 `AllowedIPs` 推断的 `routing_mode`(`split` / `global_ipv4`);旧服务端缺字段时客户端不推断全局模式。
|
||
- 不修改 SQLite、设备配置或 WireGuard Peer 授权范围。不新增第三方 logo、虚构地区和用户协议链接。
|
||
- WireGuard 配置新增可选 `auth_mode=password`;旧记录缺失时按既有客户端账号+设备密钥行为显示。只有 WireGuard 新增服务端枚举校验,`oidc` 不能写入配置;列表从 JSON 配置读取既有 OpenVPN `auth_mode`,未知配置显示未指定。启动/停止使用原有 API。
|
||
|
||
## 5. 风险与验收
|
||
|
||
| 风险 | 防护 / 恢复 | 可观察信号 |
|
||
|---|---|---|
|
||
| 将 OpenVPN OAuth 当 WireGuard 登录 | 飞书入口根据客户端能力禁用;文案区分两者 | `oidc:false` 下无法点击浏览器授权 |
|
||
| 非法 WireGuard OIDC 配置被误认为安全登录 | 下拉禁选且后端验证拒绝;保留原设备密钥与静态 Peer 流程 | 创建/编辑传 `oidc` 返回校验错误 |
|
||
| 将 HTTP 或隧道探针误称为节点 RTT | 清楚标注“隧道 TCP 建链耗时”,未测为中性 | 无数据时没有绿色/黄色毫秒值 |
|
||
| 选择全局模式导致错误路由 | 根据专线真实 AllowedIPs 显示当前策略,未具备切换条件则不可切换 | 不更改系统路由与专线配置 |
|
||
|
||
| AC | 对应需求 | 操作与预期 | 验证方式 | 结果 |
|
||
|---|---|---|---|---|
|
||
| AC-01 | FR-01 | 新用户配置地址、检测成功、进入认证;切换单位清空表单 | 客户端 UI 构建、桌面窗口启动;真实登录需账号验收 | 构建/启动通过,真实登录待验收 |
|
||
| AC-02 | FR-02 | `oidc:false` 隐藏第三方入口;`password:false` 隐藏密码入口;`oidc_provider=feishu` 显示飞书标签但保持禁用 | 客户端 UI 构建、能力契约单测;实际账号登录待验收 | 构建与契约单测通过,实际登录待验收 |
|
||
| AC-03 | FR-03 | 运行中线路可选;全局模式不在私网路由上假激活 | 路由推断 Go 单测、客户端 UI 构建 | 通过 |
|
||
| AC-04 | FR-04 | 真实探测显示毫秒数;失败显示不可测 | Go/Rust 测试、真机试验 | 测试通过,真机延迟/线路切换待验收 |
|
||
| AC-05 | FR-05 | WireGuard 创建/编辑显示两种方式,其中 OIDC 不可选;手工请求 `auth_mode=oidc` 被拒;无字段旧配置可验证 | 后台构建、Go 单测 | 通过;界面手工验收待进行 |
|
||
| AC-06 | FR-06 | 不同协议列表认证标签正确;运行和停止状态有清晰按钮 | 后台构建、代码检查 | 构建通过;界面手工验收待进行 |
|
||
|
||
## 6. 发布与恢复
|
||
|
||
先验证 Go 服务端再发布前端及桌面客户端;本轮不修改生产网关。若需回退,恢复原服务端/前端构建与桌面客户端构建;新 `auth_mode=password` 对旧服务端为普通附加字段,旧配置仍可读取。无需迁移数据库或撤销现有授权。
|
||
|
||
## 7. 待决问题
|
||
|
||
正式飞书 OIDC 需要 HTTPS issuer、应用凭据与回调域名,以及管理员确认的飞书 `issuer/sub` 对 VPNUser 授权映射;没有这些配置不得显示可用的一键登录。全局 VPN 需后续系统隧道权限、NAT 与 DNS 恢复验收。
|