Files
opsx-vpn/docs/specs/SDD-004-client-entry-and-node-choice.md

7.5 KiB
Raw Permalink Blame History

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 恢复验收。