docs: describe the unified Agent topology and link controls
Align architecture, protocol, API, storage, security and deployment documentation with default mutual measurements and the Agent link board.
This commit is contained in:
1 parent
15f0023614
commit
c9beeee8e3
16 files changed
+363
-383
No files matched your search
@@ -48,7 +48,7 @@
|
||||
| 组 | 能力 | 说明 | 信任类 |
|
||||
| --- | --- | --- | --- |
|
||||
| 展示 | `public.read` | 看隐藏线路;站点私有时看展示页 | |
|
||||
| 节点 | `fleet.read` | 看 Agent、Probe、线路、加入代码 | |
|
||||
| 节点 | `fleet.read` | 看 Agent、线路、加入代码 | |
|
||||
| | `fleet.write` | 改名、标签、可见性、手填地址、线路开关、断开会话 | |
|
||||
| | `fleet.enroll` | 生成加入代码 | |
|
||||
| | `fleet.revoke` | 吊销或删除节点 | 是 |
|
||||
@@ -75,7 +75,7 @@
|
||||
| passkey | WebAuthn,只支持 ES256,attestation 一律当 `none`;可以登录,也能给操作员集合签名(节点验证) |
|
||||
|
||||
- 两种方式的会话拿同样的能力。passkey 只用在节点自己会验证的事上,见第 5 节。
|
||||
- 认领向导(没有默认账户):面板里还没有任何用户时,打开 `/admin/` 进向导——用后端日志里的认领码(或 `MoShiro__ClaimCode`)创建第一个管理员(用户名和密码自己填),注册第一个 passkey,再用它给操作员集合签名建立信任根。谁先打开页面谁就能当管理员,所以要认领码;创建完码作废、入口关闭(`POST /api/admin/auth/setup` 之后返回 409)。后两步是引导不是门槛,可以稍后补;不注册 passkey、不建立信任根,就添加不了 Agent 和 Probe,只能进面板做基础管理,这是架构如此。之后新增的 passkey 不会自动成为操作员:要由现有操作员在信任页看清「新增了哪些」再签新版本,节点才认。
|
||||
- 认领向导(没有默认账户):面板里还没有任何用户时,打开 `/admin/` 进向导——用后端日志里的认领码(或 `MoShiro__ClaimCode`)创建第一个管理员(用户名和密码自己填),注册第一个 passkey,再用它给操作员集合签名建立信任根。谁先打开页面谁就能当管理员,所以要认领码;创建完码作废、入口关闭(`POST /api/admin/auth/setup` 之后返回 409)。后两步是引导不是门槛,可以稍后补;不注册 passkey、不建立信任根,就添加不了 Agent,只能进面板做基础管理,这是架构如此。之后新增的 passkey 不会自动成为操作员:要由现有操作员在信任页看清「新增了哪些」再签新版本,节点才认。
|
||||
- 建议每个账户至少注册两个 passkey(手机加硬件密钥)。
|
||||
|
||||
### 4.1 passkey 登录的实现
|
||||
@@ -121,7 +121,7 @@ CI 把签名清单 POST 给 `POST /api/release/offer`,面板用发布公钥验
|
||||
|
||||
## 7. 归属与审计
|
||||
|
||||
- 加入代码记 `created_by`,节点记 `added_by`;管理页的 Agent、Probe 详情显示「由 xxx 于 xxx 添加」。
|
||||
- 加入代码记 `created_by`,节点记 `added_by`;管理页的 Agent 详情显示「由 xxx 于 xxx 添加」。
|
||||
- 审计日志(`GET /api/admin/audit`):所有非 GET 的管理操作和登录自动记录(时间、账户、登录方式、动作、对象、详情)。写不进去只记日志,不让已完成的操作报错。保留 365 天,只追加。
|
||||
|
||||
## 8. 入网信任链的实现要点
|
||||
@@ -136,19 +136,19 @@ CI 把签名清单 POST 给 `POST /api/release/offer`,面板用发布公钥验
|
||||
|
||||
## 9. 节点属主与 extension 授权
|
||||
|
||||
extension(web ssh、文件、抓包,见 [security.md](security.md))现在都不实现,Agent 和 Probe 一样。这类能力连管理员都不信任:管理员能删,不能读,也不能用。所以入网时就给每个节点固定「属主」,之后不用重装节点。
|
||||
extension(web ssh、文件、抓包,见 [security.md](security.md))现在都不实现,Agent 一样。这类能力连管理员都不信任:管理员能删,不能读,也不能用。所以入网时就给每个节点固定「属主」,之后不用重装节点。
|
||||
|
||||
已经实现的部分
|
||||
|
||||
- 属主 `controllers` 是一组 passkey 凭证 id,必须是操作员集合里的凭证。由安装命令带来,节点注册时写进 `trust.json`,Backend 之后改不了。
|
||||
- 每个 Agent 和 Probe 都必须有属主,至少一把。这由节点自己强制:节点启动时检查本地固定的属主,没有(或者属主的 passkey 已经不在操作员集合里)就不运行(共用 `Fleet.Hosting` 里的 `OwnerGuard`;配置 `fleet.require_owner`,`MOSHIRO_ALLOW_NO_OWNER=1` 放行)。面板被攻破也改不了。
|
||||
- 每个 Agent 都必须有属主,至少一把。这由节点自己强制:节点启动时检查本地固定的属主,没有(或者属主的 passkey 已经不在操作员集合里)就不运行(共用 `Fleet.Hosting` 里的 `OwnerGuard`;配置 `fleet.require_owner`,`MOSHIRO_ALLOW_NO_OWNER=1` 放行)。面板被攻破也改不了。
|
||||
- 添加节点时选属主:`POST /api/admin/join-tokens` 的 `controllers: [credential_id…]`,不给就是操作员集合里的全部凭证;给了就必须非空且都在集合里。还没有信任根或一把属主都没有时,面板提前拒绝创建加入码(400,字段 `controllers`),这只是尽早失败,真正的强制在节点;`MoShiro__RequireOwner=false` 可以关掉这个提前检查(只给没有信任根的老部署)。界面里是必选的「属主(passkey)」多选列表,只是选,不用触碰。
|
||||
- 安装端也强制:`install.sh`、`install.ps1`、容器入口缺了 `MOSHIRO_GENESIS` 或 `MOSHIRO_CONTROLLERS` 就不装;`fleet-enroll --genesis` 不带 `--controllers` 也拒绝。
|
||||
- 逆推出绑定关系:节点握手时把本地固定的属主(passkey 凭证 id)报给面板(hello 的 `owners`),面板顺着凭证 id 反查出它绑定在哪个账户的哪把 passkey 上,显示在「系统 → 版本」的「属主」列(对不上任何已注册 passkey 的显示「未知凭证」)。上报只是自述,真正的授权由节点自己校验 passkey 签名。
|
||||
|
||||
预留的设计(还没做)
|
||||
|
||||
- 谁来强制:节点本地。web ssh 这类会话要不要加密、要不要验证,由 Agent 和 Probe 自己要求。让 Backend 决定,被攻破的 Backend 一句「这次不用加密」就绕过去了。节点本地强制:没有操作员的现场证明不启动会话;会话密钥只和证明里的那把密钥协商,不和 Backend 转来的公钥协商;加密字段缺失就拒绝,不降级;能开哪些 extension、哪些 passkey 能授权,只看本节点属主。
|
||||
- 谁来强制:节点本地。web ssh 这类会话要不要加密、要不要验证,由 Agent 自己要求。让 Backend 决定,被攻破的 Backend 一句「这次不用加密」就绕过去了。节点本地强制:没有操作员的现场证明不启动会话;会话密钥只和证明里的那把密钥协商,不和 Backend 转来的公钥协商;加密字段缺失就拒绝,不降级;能开哪些 extension、哪些 passkey 能授权,只看本节点属主。
|
||||
- 证明的方向是反的:节点先出题(nonce 加它的临时公钥,用节点身份密钥签名),属主的浏览器把 nonce 和自己的临时公钥放进 passkey 断言的挑战里;节点验断言来自本节点属主、要求用户验证、nonce 是自己刚出的且没用过。Backend 仍然管谁有资格发起请求、审计、限流、转发密文。
|
||||
- 交互式会话(终端、ssh)用现场签名的临时 ECDH 密钥协商,passkey 只签名授权,不参与解密,所以不支持 PRF 的 passkey 也能用,还有前向保密;之后双向是带序号的 AEAD。静态数据(抓包文件、会话录像)需要事后解密,才用属主记录里的接收者公钥加密(来自 WebAuthn PRF 或浏览器里不可导出的密钥)。
|
||||
- 删除和使用分开:admin 能删节点、卸载 extension,读不到也用不了。改属主要现有属主的 passkey 签名(`ControllerUpdate`),账户被删、角色被改都改不了某个节点的属主。属主是 passkey 凭证,不是账户;一个人丢了全部属主 passkey,这个节点上的 extension 就没人能用了,所以添加时建议绑两把以上。
|
||||
@@ -182,7 +182,7 @@ macOS 用 `shasum -a 256 -c`,Windows 用 `Get-FileHash` 比较,不通过就
|
||||
|
||||
④ 其余
|
||||
|
||||
- 角色(Agent 还是 Probe)、镜像仓库地址仍由代码决定,但镜像身份由签名清单决定。
|
||||
- 角色(Agent 还是 拨号方)、镜像仓库地址仍由代码决定,但镜像身份由签名清单决定。
|
||||
- macOS 的 Developer ID 签名和公证、Windows 的 Authenticode 需要证书,目前没有做。
|
||||
|
||||
## 11. 运行中的二进制不做校验
|
||||
|
||||
Reference in new issue
Block a user