TunnelMesh 安全授权、稳定性与发布运维设计
TunnelMesh 安全授权、稳定性与发布运维设计
日期: 2026-09-06
状态: 已确认设计,待实施计划
范围: 独立作用域 Token、TLS/WSS、Agent 运行质量、网络探针、线路保活、结构化日志、进程保活、多平台发布和 Nginx 部署。
1. 目标与非目标
1.1 目标
- 让 Agent、Client、Server-node 和管理用户使用相互隔离的凭据。
- 让所有公网长连接在 TLS 保护下运行,并对每一条逻辑流重复执行授权和 Policy 检查。
- 为 Agent 提供可观测的活跃状态、质量、带宽、延迟、重连和探针结果。
- 让异常网络可以按连接阶段定位,并让长连接在网络抖动下自动保活、降级和重连。
- 提供 Linux、macOS、Windows 和 Docker 的可重复发布、安装、升级和回滚文档。
1.2 非目标
- 不实现自定义加密算法或第二套 SSH 协议。
- 不把业务 payload、SSH 字节、Token 明文或 metadata 敏感值写入日志和指标。
- 不让 Server 进程自行 daemon 化;进程保活交给 systemd、launchd、Windows Service 或容器编排器。
- 不把 Prometheus 变成管理数据权威来源;Agent、Token、Policy 和 Tunnel 仍以数据库为权威。
2. 子项目拆分
该需求拆为三个可以独立验收的子项目:
| 子项目 | 主要交付 | 依赖 |
|---|---|---|
| A. 安全凭据与连接授权 | Token 生命周期、作用域、Client WS 鉴权、TLS 配置、审计 | 现有 auth、API、Agent WS |
| B. 可观测性与网络稳定性 | PING/PONG、连接阶段、探针、质量聚合、metrics、诊断 API、结构化日志 | A 的 token identity;现有 relay/session |
| C. 发布和运维 | GoReleaser/Makefile、多平台归档、Nginx、systemd/launchd/Windows Service、升级回滚 | A/B 的配置和健康端点 |
每个子项目都必须先写失败测试,再实现最小行为,最后运行跨包和竞态验证。
3. 安全模型
3.1 Token 类型
新增独立的长期凭据实体,数据库只保存不可逆哈希:
agent_token:绑定单个 Agent,只能用于/ws/agent。client_token:绑定用户,用于/ws/client、proxy和转发连接。server_node_token:绑定 Server node,只用于集群节点注册、续租和节点间转发。user_token:现有管理 API 登录凭据,只用于管理 API。
Token 元数据包含:ID、类型、owner、前缀、哈希、scope JSON、创建时间、过期时间、最后使用时间、撤销时间、状态和审计引用。Token 明文只在创建/轮换响应中显示一次。
3.2 Scope 与授权顺序
client_token 的权限不能超过用户拥有的 Agent Policy:
TLS/WSS
-> Token 哈希和状态校验
-> Token 类型校验
-> owner/resource scope 校验
-> Agent Policy 校验
-> 创建逻辑流
Token 可以收紧 Agent、协议、目标 CIDR 和端口范围,但不能放宽数据库中的 Agent Policy。每个逻辑流 OPEN 都必须重新执行 scope 和 Policy 检查,不能只依赖 WebSocket 建连时的授权。
3.3 TLS 与 WebSocket
- 公网只暴露 80/443;80 只重定向到 443。
- 管理 API、后台、Agent WS 和 Client WS 使用 HTTPS/WSS。
- 默认 TLS 1.2+,推荐 TLS 1.3;客户端默认校验证书。
- Server 可配置原生 TLS 监听;生产推荐 Nginx/负载均衡终止边缘 TLS。
- Nginx 到 Server 可选内网 HTTP 或 HTTPS;Server-node 链路强制 mTLS,应用层仍校验
server_node_token。 - Token 只允许放在
Authorization: Bearer,禁止 query string、Cookie 和 URL path。 - WebSocket 校验 Host/Origin 白名单和 Upgrade 头,禁止不受信任来源复用后台会话。
3.4 Token 后台管理
后台和 API 提供:创建、列表、查看元数据、撤销、轮换、设置过期时间和 scope。创建接口使用 Idempotency-Key,轮换产生新 Token 并原子撤销旧 Token。所有变更和授权拒绝写审计日志,日志只包含 token ID/前缀。
4. 连接协议与稳定性
4.1 心跳和租约
- Agent/Client 与 Server 默认每 30 秒发送协议
PING,Server 回PONG。 - 连续 3 个心跳周期无响应,连接状态置为
degraded,随后主动关闭并按指数退避 + jitter 重连。 - Agent metadata lease 由心跳刷新,不改变 metadata revision;旧 epoch 不能续租新 epoch。
- Server-node 使用独立租约周期和 epoch fencing。
- TCP socket 启用操作系统 keepalive;UDP association 使用 idle timeout,并支持协议级 keepalive。
- 正常关闭先发送 GOAWAY,等待受限 drain;超时后强制关闭。
4.2 连接阶段诊断
每条长连接维护以下阶段:
resolve -> tcp_connect -> tls_handshake -> websocket_upgrade
-> token_auth -> agent_hello -> heartbeat -> logical_stream
每阶段记录 trace_id、connection_id、agent_id、token_id、开始/结束时间、耗时、错误分类和重试次数。日志和 API 不返回目标服务响应内容。
4.3 主动网络探针
诊断 API 支持 Server → Agent → 目标地址的 TCP connect、HTTP HEAD/GET 和 UDP echo。探针必须经过同一 Agent Policy,默认不使用需要 root 权限的 ICMP。探针结果只返回状态码、耗时、错误分类和时间戳;不返回业务响应正文。
5. 运行指标与后台展示
5.1 实时状态
Agent 详情页展示:在线状态、版本、系统、架构、节点、启动时间、连接时长、Token 状态、epoch、最后心跳、重连原因、活跃流数、总字节、当前带宽、控制 RTT、目标探针 RTT、心跳成功率和最近错误分类。
状态枚举为 online、degraded、offline、stale。质量页同时展示原始指标,不用单一分数掩盖异常:
- heartbeat availability;
- control RTT P50/P95;
- reconnect rate;
- probe success rate;
- stream error rate;
- inbound/outbound bps 和峰值。
5.2 存储和指标
- Server 内存保存短窗口统计。
- 每 60 秒写一条
agent_runtime_stats聚合快照,默认保留 7 天,支持配置。 - 快照包含
node_id + agent_id + epoch,旧 epoch 不能覆盖新连接。 - Prometheus 指标提供长期监控来源;数据库仍是管理 API 的权威来源。
- 不保存业务 payload、SSH 内容、Token 明文或敏感 metadata。
5.3 管理接口
GET /api/v1/agents/{id}/runtime
GET /api/v1/agents/{id}/metrics?range=5m
GET /api/v1/agents/{id}/probes
POST /api/v1/agents/{id}/diagnose
接口仅允许 Agent owner/admin 访问;诊断请求必须再次经过 Agent Policy。
6. 日志、指标和进程保活
6.1 结构化日志
JSON 日志字段统一包含时间、级别、组件、事件名、trace_id、connection_id、agent_id、node_id、token_id、epoch、错误分类和耗时。关键事件包括启动、配置来源、schema 初始化、Token 管理、连接重连、探针失败、目标不可达、Server-node 租约、GOAWAY 和优雅退出。
严禁记录 Token、密码、私钥、完整硬件指纹、metadata 敏感值、SSH 字节和业务 payload。日志级别支持 error、warn、info、debug,生产默认 info。
6.2 进程生命周期
程序响应 SIGTERM/CTRL_BREAK:停止接受新连接、发送 GOAWAY、等待有限时间、关闭数据库和 listener。进程不自行 fork 或后台化:
- Linux 使用 systemd
Restart=on-failure、Watchdog 和ExecStartPre配置校验; - macOS 使用 launchd
KeepAlive和标准输出/错误日志路径; - Windows 使用 Windows Service recovery actions;
- Docker/Compose 使用非 root、healthcheck 和
restart: unless-stopped。
7. 多平台发布
使用 Makefile + GoReleaser 构建三个二进制:
make release VERSION=v0.1.0
目标为 Linux amd64/arm64、macOS amd64/arm64、Windows amd64/arm64。每个平台输出归档包、SHA256 校验文件、版本/commit/build time 信息;构建默认 CGO_ENABLED=0。Token、配置和数据库不进入发行物。
文档覆盖安装、首次启动、配置文件、升级、回滚、Token 轮换、日志目录和卸载;Docker 仍提供 server/agent/client 三种镜像。
8. Nginx 部署约束
Nginx 必须分别配置 /api/、/、/ws/agent 和 /ws/client。WebSocket location 使用 HTTP/1.1、Upgrade/Connection、Authorization 和 X-Forwarded-* 透传,关闭 buffering,proxy_read_timeout/proxy_send_timeout 大于心跳周期。80 端口只做 HTTPS 重定向;不得把 Token 拼到 URL;泛域名只由 Server 解析。
9. 失败处理与兼容性
- 数据库不可用:管理 API 进入 not-ready;已有数据流按已有连接策略运行,禁止伪造授权结果。
- Token 服务错误:拒绝新连接,保留已有连接直到租约/心跳失败。
- 探针失败:只标记质量和错误分类,不自动修改用户 Policy。
- 统计写入失败:保留内存窗口并告警,不阻断转发主链路。
- 新增协议帧和 API 必须版本化;旧 Agent 对未知诊断帧应安全忽略,不得关闭正常数据流。
10. 验收与测试
安全
- Token 类型、owner、scope、过期、撤销、轮换和幂等测试;
- 管理 API 权限、审计和明文只返回一次测试;
- Agent/Client/Server-node 错误 Token 互拒测试;
- 每条 logical stream 重复执行 Policy 测试;
- TLS/WSS、Origin、Authorization 透传和 query token 拒绝测试。
稳定性
- PING/PONG、三次心跳超时、重连退避和 epoch fencing 测试;
- TCP/UDP/HTTP 探针成功、超时、拒绝和不泄露响应正文测试;
- 带宽、RTT、P95、重连和活跃流聚合测试;
- Server 重启、数据库短暂不可用、网络抖动和优雅退出 E2E 测试;
- 结构化日志脱敏、trace 字段和错误分类测试。
发布
- Linux/macOS/Windows 交叉构建和归档校验;
- Nginx 配置语法和 WebSocket Upgrade 冒烟测试;
- systemd/launchd/Windows Service/Docker 文档命令可验证;
go test ./...、go test -race ./...、go vet ./...、前端测试/build、git diff --check。