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
+33
-63
@@ -1,66 +1,34 @@
|
||||
# MoShiro 的注册与身份
|
||||
|
||||
通用的注册、身份、认证机制由 Fleet 提供,见 [Fleet 文档](../../backend/fleet/README.md) 的「身份」「注册」两节。本文只描述 MoShiro 在 Fleet 之上的约定:Agent 注册后如何自动接入测量、Probe 的身份以及 Agent 列表同步,以及节点本地的硬上限。
|
||||
通用注册、认证和信任链由 [Fleet](../../backend/fleet/README.md) 提供。MoShiro 统一使用 Agent 节点;监听方、拨号方描述一次测量会话中的方向,同一 Agent 可以同时承担两侧工作。
|
||||
|
||||
## 1. 身份一览
|
||||
## 1. 身份
|
||||
|
||||
| 主体 | 凭据 | 生成方 | Backend 保存 |
|
||||
| --- | --- | --- | --- |
|
||||
| Agent | Fleet 节点身份(ECDSA P-256)+ 面向 Probe 的 TLS 证书 | `fleet-enroll` | 公钥、SPKI 指纹 |
|
||||
| Probe | Fleet 节点身份(连面板)+ 另一把独立的密钥(连 Agent,放在 `tls.pfx`) | `fleet-enroll`,和 Agent 一样用加入令牌(`role=probe`);可以有多个 Probe,每个独立吊销 | 两把公钥 |
|
||||
| 面板用户 | 账号 + 密码(PBKDF2-SHA256) | 面板 | 密码哈希 |
|
||||
| API 令牌 | 随机高熵令牌,带一组能力(见 [access.md](access.md)) | 面板 | SHA-256 |
|
||||
| 发布签名 | ECDSA P-256 发布密钥 | CI(Woodpecker 密钥 `release_signing_key`)或离线环境 | 只在宿主机的更新器里配置公钥(Backend 和脚本装的节点用 `moshiro-update`,见 [deployment.md](../ops/deployment.md);Quadlet 节点不验证清单,只是退出后重新拉镜像;纯二进制节点的更新见[路线图](../roadmap.md)),面板不保存私钥;登记清单时面板用公钥验签,宿主机的更新器之后再验一次 |
|
||||
`fleet-enroll` 在节点本地生成连接 Backend 的 ECDSA P-256 身份密钥,以及 TLS 证书中的独立对等身份密钥。拨号和监听共用该节点的对等身份。Backend 保存公钥与 SPKI 指纹,不接收私钥。节点固定操作员集合的创世指纹和属主,并在注册、连接及状态同步时验证信任链。
|
||||
|
||||
## 2. Agent 接入流程
|
||||
面板用户通过密码或 Passkey 登录;API 令牌带有明确的能力集合,服务端保存令牌哈希。发布清单使用独立发布密钥签名,该私钥不进入面板或仓库。更新器在节点进程之外执行,具体边界见 [deployment.md](../ops/deployment.md) 和 [access.md](access.md)。
|
||||
|
||||
## 2. 接入
|
||||
|
||||
```text
|
||||
管理员 ── 创建加入令牌 {标签, max_uses, 过期时间, auto_approve, controllers} ──> 面板(Fleet.Server.Enrollment)
|
||||
<── 一段 Quadlet 安装命令(默认,Podman 系;Docker 另有 compose 命令):把面板地址、一次性码、创世指纹和属主写进本地 env,下载面板提供的静态
|
||||
Quadlet 单元并核对 SHA-256,再启动用户服务;命令里只有公开的值(见 access.md 第 10 节)。
|
||||
备用:一行安装脚本(先核对脚本哈希再执行),参数走环境变量
|
||||
|
||||
两条路径做的事一样:容器的入口脚本,或 install.sh / install.ps1(packaging/install/,嵌入 Backend,静态文件,不替换任何值):
|
||||
├─ 向面板取 CI 签名的发布清单,用脚本里内置的发布公钥验签,按清单里的 digest 拉镜像
|
||||
├─ 用 Docker 或 Podman 起容器,身份和配置存在命名卷里;节点名字默认取主机名
|
||||
└─ 容器入口用代码注册:fleet-enroll --server … --join jt_… --genesis … --controllers …
|
||||
├─ 先验操作员集合链(创世指纹、属主在集合里),验不过就不交出密钥
|
||||
├─ 注册元数据(MoShiro 定义):{ probe_tcp_port, probe_quic_ports, public_host?, kinds[] }
|
||||
└─ 写 trust.json(创世指纹、链、属主)和 agent.json(本地硬上限)
|
||||
下载压缩包的二进制安装(packaging/install.sh)做同样的注册,另外创建系统用户 moshiro、启用 moshiro-agent.service,见 deployment.md。
|
||||
|
||||
面板收到 OnEnrolled(MoShiro 挂钩)
|
||||
├─ public_host 未提供时,来源 IP 是公网地址才用;之后 hello 里 Agent 上报本机公网地址(`addresses`),面板自动填 public_host 和 ipv6_host,手填的优先
|
||||
├─ 按“线路任务模板”为该 Agent 计算有效任务集(TaskSet)
|
||||
└─ 面板把新的 Agent 列表作为期望状态推给所有 Probe → Probe 自动连接新 Agent
|
||||
从安装到开始出数据,全程不需要手工配置
|
||||
管理端创建加入令牌(统一 agent)
|
||||
-> 安装命令携带面板地址、一次性码、创世指纹、属主和脚本哈希
|
||||
-> fleet-enroll 验证信任链并在本机生成身份
|
||||
-> Agent 连接 Backend,上报监听信息与本地能力
|
||||
-> Backend 推送 task_set 和 dial_targets
|
||||
-> Agent 调和拨出连接,同时接受名册内其他 Agent 的接入
|
||||
```
|
||||
|
||||
名称冲突、审批、接管、禁用等行为都采用 Fleet 的默认规则。
|
||||
同名节点进入待审批状态,由管理员决定是否接管。激活、停用、接管和删除通过统一的 Agent API 完成。
|
||||
|
||||
## 3. Probe 身份与 Agent 列表同步
|
||||
Backend 默认启用 `fleet.auto_link`,所有 Agent 向其他可拨号 Agent 建立线路,自连接被排除。A→B、B→A 是两个独立方向;手动线路开关优先于自动连接。节点本地 `listen.enabled` 默认 true,可显式关闭,不产生另一种节点角色。
|
||||
|
||||
Probe 直接连面板(Fleet 长连接,身份是下面生成的密钥),Agent 列表由面板作为期望状态下发;测量数据仍然只走 Probe → Agent。
|
||||
## 3. 任务、拨号目标与状态
|
||||
|
||||
```text
|
||||
面板:POST /api/admin/join-tokens {role: "probe"} → 一次性加入令牌 jt_…
|
||||
Probe 机器:fleet-enroll --server … --join jt_… --name home --identity-dir …
|
||||
├─ 本地生成两把密钥:node.key(连面板认证)和 tls.pfx 里的密钥(连 Agent 对端认证);面板从不接触私钥
|
||||
├─ 注册请求带两把公钥(pubkey、tls_pubkey)和持有证明;面板据此写 probes 记录,ID 前缀 prb_
|
||||
└─ 吊销 /revoke 会让面板和所有 Agent 断开它;换密钥 = 吊销后重新注册(没有 rotate)
|
||||
probe.json:{ fleet: { server, identity_dir }, restart_at?, limits? } ← limits 是本地硬上限,面板无法修改;在路由器上建议调低
|
||||
|
||||
Probe 启动
|
||||
├─ 连接 server:Fleet 长连接(用 probe_id 和私钥认证),fleet.hello 带上系统、架构和构建信息
|
||||
├─ 面板推送期望状态 probe_agents:{ version, agents: [ {agent_id, host, tcp_port, quic_ports, public_key}... ] }
|
||||
├─ 调和:新增的 Agent → 建立点对点会话(peer 用途签名);被移除或禁用的 → 断开
|
||||
└─ 之后列表的任何变化(Agent 注册、禁用、地址或证书变化),面板都重新推送同一种期望状态;
|
||||
Probe 用 Fleet.Hosting.ConfigStore 把最新列表写回 agents.json(这是配置,不是测量数据;面板暂时连不上时,Probe 靠它继续测量)
|
||||
```
|
||||
|
||||
- 每个 Agent 通过自己的期望状态(`TaskSet.peers`)获得 Probe 的公钥,用来验证点对点会话的签名。
|
||||
- 哪些 Probe 连哪些 Agent 由面板决定,始终是 Probe 主动拨出:设置 `fleet.auto_link`(默认开)打开时,所有未吊销的 Probe 和所有 Agent 两两连;关闭时只连手动选中的。每一对还可以在管理端 Probe 页的「线路」矩阵里手动强制开或关(`PUT /api/admin/links/{probe_id}/{agent_id}`),手动设置优先于自动连接。结果同时用在 Probe 的 Agent 列表、Agent 的 `peers` 和线路目录(关掉的线路从总览里消失,历史数据还在)。
|
||||
- 吊销 Probe:`POST /api/admin/probes/{id}/revoke`,旧公钥立即从所有 Agent 的期望状态中移除,旧会话随之断开;要继续用就重新注册。
|
||||
- `TaskSet.peers` 下发允许接入的节点公钥。
|
||||
- `DialTargets` 下发目标节点的地址、端口、证书公钥和 IP 路径。节点在 `dial_targets.json` 中缓存已验证的目标文档。
|
||||
- 节点集合、地址、证书或线路策略变化后,Backend 重算并推送期望状态。节点断开已移除的目标,并连接新增目标。
|
||||
- 每个 Agent 通过自身的 Backend 心跳上报运行状态、拨出线路的控制层和任务层健康、错误与重试,以及接入会话快照。测量流量走节点直连,监听方合并列块后上传原始数据。
|
||||
|
||||
## 4. Agent 本地配置(`/etc/moshiro/agent.json`,面板无法修改)
|
||||
|
||||
@@ -87,23 +55,25 @@ Probe 启动
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| POST | `/api/agent/v1/enroll` | 由 `MapFleetEnrollment` 提供 |
|
||||
| GET | `/api/agent/v1/rpc` | 由 `MapFleetLink` 提供(升级为 WebSocket) |
|
||||
| GET/POST/DELETE | `/api/admin/join-tokens` | 管理加入令牌 |
|
||||
| POST | `/api/admin/agents/{id}/approve`、`/disable`、`/enable`、`/takeover` | 审批与启停 |
|
||||
| GET/PATCH/DELETE | `/api/admin/probes`、`/probes/{id}` | Probe 的列表、改名、删除 |
|
||||
| POST | `/api/admin/probes/{id}/revoke` | 吊销(换密钥就是吊销之后重新注册,没有轮换) |
|
||||
| POST | `/api/admin/agents/{id}/probes/{probe_id}/disconnect` | 让 Agent 断开某个 Probe |
|
||||
| GET | `/install`、`/install.ps1` | 静态安装脚本(Agent 和 Probe 共用,不带参数,哈希在一个版本内固定) |
|
||||
| GET | `/install/manifest?code=…`、`/install/manifest.sig?code=…` | 凭一次性代码取该角色已签名的发布清单(原样,一个字节也不改) |
|
||||
|
||||
| POST | `/api/agent/v1/enroll` | 注册节点 |
|
||||
| GET | `/api/agent/v1/rpc` | WebSocket 节点链路 |
|
||||
| GET/POST/DELETE | `/api/admin/join-tokens` | 加入令牌 |
|
||||
| GET | `/api/admin/agents` | 统一节点列表 |
|
||||
| GET/PATCH/DELETE | `/api/admin/agents/{id}` | 节点详情、修改、删除 |
|
||||
| POST | `/api/admin/agents/{id}/approve`、`/disable`、`/enable`、`/takeover` | 审批、启停与接管 |
|
||||
| POST | `/api/admin/agents/{id}/dialers/{dialer_id}/disconnect` | 关闭指定接入会话 |
|
||||
| GET | `/api/admin/links` | 有向线路矩阵与连接状态 |
|
||||
| PUT | `/api/admin/links/{dialer_id}/{listener_id}` | 设置单方向线路策略 |
|
||||
| POST | `/api/admin/links/{dialer_id}/{listener_id}/retry` | 开启并立即重试 |
|
||||
| GET | `/install`、`/install.ps1` | 静态安装脚本 |
|
||||
| GET | `/install/manifest?code=…`、`/install/manifest.sig?code=…` | 原样的签名发布清单及签名 |
|
||||
|
||||
## Agent 的本地配置:主机状态上报
|
||||
|
||||
`agent.json` 和 `probe.json` 的 `reporting` 段(面板无法修改):
|
||||
`agent.json` 的 `reporting` 段(面板无法修改):
|
||||
|
||||
```json
|
||||
{ "reporting": { "host_stats": true, "host_interval_s": 2 } }
|
||||
```
|
||||
|
||||
`host_stats` 为 true(默认)时,Agent 和 Probe 每隔 `host_interval_s` 秒用 `moshiro.host` 上报一份主机资源占用的汇总数字(CPU、内存、根分区、网卡累计流量与网速、运行时长;没有型号、主机名、IP);设为 false 就一个字也不上报。
|
||||
`host_stats` 为 true(默认)时,Agent 每隔 `host_interval_s` 秒用 `moshiro.host` 上报一份主机资源占用的汇总数字(CPU、内存、根分区、网卡累计流量与网速、运行时长;没有型号、主机名、IP);设为 false 就一个字也不上报。
|
||||
Reference in new issue
Block a user