[feat] authenticate controller sessions with device keys

This commit is contained in:
dijunkun
2026-11-02 03:00:18 +08:00
parent adcb0f17dd
commit 425698e22e
5 changed files with 6 additions and 8 deletions
+3 -3
View File
@@ -181,16 +181,16 @@ WSS 在连接成功后继续承担心跳和会话关闭消息。当前心跳约
| 场景 | 登录身份及职责 |
| --- | --- |
| 本机常驻 Peer | 使用缓存 ID 和本地 Ed25519 私钥完成挑战签名,服务端按该 ID 绑定的公钥验签 |
| 控制端会话 Peer | 以 `C-<本机ID>` 登录;目标设备的密码在后续 Join 中提交,不附加在该登录身份中 |
| 控制端会话 Peer | 以 `C-<本机ID>` 完成同一私钥的挑战签名,服务端核对原 ID 的公钥;目标密码在后续 Join 中提交 |
| 首次身份分配 | 无缓存身份时,以空 `user_id` 和本机公钥发起挑战;证明私钥持有权后,服务端原子分配 ID、远控密码并绑定公钥 |
每次登录和重连都先请求 `login_challenge`,再签署规范 JSON 数组 `["crossdesk.device-login.v1", ID, 公钥, 随机挑战]`。挑战为 32 字节随机数,只属于当前 WSS 连接,有效期 10 秒,验证尝试时即消费。已绑定 ID 的签名登录不进入密码计算队列,也不读取密码失败计数;伪造签名不能锁定该 ID。服务端另外限制挑战来源和待处理数量,仍受连接及消息资源上限约束。
旧 ID 首次升级时,客户端先完成签名证明,再按服务端要求提交原有密码;密码验证成功后仅允许绑定一次公钥,保留 ID 和密码。绑定后撤销旧重连令牌并拒绝密码登录,不能用密码覆盖公钥;尚未完成绑定的旧 ID 仍受原密码限流。部署时先升级服务端;新桌面客户端要求签名协议,不自动回退到旧服务端的密码登录。混部或回滚到忽略公钥绑定的旧服务端会失去这项保护。
旧 ID 首次升级时,客户端先完成签名证明,再按服务端要求提交原有密码;密码验证成功后仅允许绑定一次公钥,保留 ID 和密码。绑定后撤销旧重连令牌并拒绝密码登录,不能用密码覆盖公钥;尚未完成绑定的旧 ID 按来源 IP 及“来源 IP → 目标 ID”限流,不保留目标 ID 的总失败次数。部署时先升级服务端;新桌面客户端要求签名协议,不自动回退到旧服务端的密码登录。混部或回滚到忽略公钥绑定的旧服务端会失去这项保护。
MiniRTC 的可选 `OnSignalExchange` 回调提供登录请求替换、入站消息处理及回复发送能力,不包含设备密钥、可信名单或 CrossDesk 协议字段。应用层负责签名和协议状态;未配置回调的使用方保留原有登录及内存重连令牌行为。改密中断后,签名登录不代表待定密码已生效,客户端重发持久保存的改密请求,收到成功回复后才更新本地密码。
连接目标设备时,控制端会话 Peer 仍将 `目标ID@目标密码` 放入 Join,由服务端返回成功、凭据错误、限流或繁忙结果。设备签名登录仅证明本机 ID 所有权,不授予控制其他设备的权限。
连接目标设备时,控制端会话 Peer 仍将 `目标ID@目标密码` 放入 Join,由服务端返回成功、凭据错误、限流或繁忙结果。设备签名登录仅证明本机 ID 所有权,不授予控制其他设备的权限。服务端按已验证控制端 B 和“B → A”组合累计失败(分别为 20/5 次),不保留 A 的总失败次数;B 的失败不会触发 C 连接 A 的密码冷却。认证队列和计算额度也按已验证控制端隔离。未验证的旧客户端、Web/CLI 临时身份按来源 IP 处理,无法通过自称 `C-B` 获得 B 的预算。已绑定 B 的 `C-B` 登录必须支持签名协议;同一 NAT 下旧客户端仍共享 IP 限制,显式 IP 风控与服务器资源上限仍然适用。
信令 TLS 与远控数据加密属于两条路径。原生远控的 DTLS 握手和 SRTP 处理位于 MiniRTC,不能把“信令使用 TLS”等同于“画面经 TLS WebSocket 传输”。