Files
MoShiro/docs/enrollment.md
T
2026-10-04 21:46:39 +08:00

105 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Monitor 的注册与身份
通用的注册、身份、认证机制由 Fleet 提供,见 [fleet/link.md](fleet/link.md) 第 2~3 节。本文只描述 **Monitor 在 Fleet 之上的约定**:Agent 注册后如何自动接入测量、Probe 的身份以及 Agent 列表同步,以及节点本地的硬上限。
## 1. 身份一览
| 主体 | 凭据 | 生成方 | Backend 保存 |
| --- | --- | --- | --- |
| Agent | Fleet 节点身份(ECDSA P-256)+ 面向 Probe 的 TLS 证书 | `fleet-enroll` | 公钥、SPKI 指纹 |
| Probe | Fleet 节点身份 | 面板生成 `probe.json`(可以有多个 Probe,每个独立吊销) | 公钥 |
| 面板用户 | 账号 + 密码(PBKDF2-SHA256) | 面板 | 密码哈希 |
| API 令牌 | 随机高熵令牌,作用域为 `read` 或 `admin` | 面板 | SHA-256 |
| 发布签名 | 离线的 ECDSA 发布密钥 | CI 或离线环境 | 只在节点的 `fleet-updater` 中配置公钥,**面板不保存** |
## 2. Agent 接入流程
```text
管理员 ── 创建加入令牌 {标签, max_uses, 过期时间, auto_approve} ──> 面板(Fleet.Server.Enrollment)
<── 安装命令:
curl -fsSL https://panel/install.sh | sh -s -- --join jt_xxx --name jp-1
install.sh(只做安装,不包含任何远程控制功能)
├─ 下载 monitor-agent、fleet-enroll、fleet-updater,并验证发布签名
├─ 创建系统用户:monitor(运行 Agent)、fleet-update(运行更新器)
├─ fleet-enroll --server https://panel --join jt_xxx --name jp-1 --identity-dir /etc/monitor
│ └─ 注册元数据(Monitor 定义):{ probe_tcp_port, probe_udp_ports, public_host?, kinds[] }
├─ 写入 agent.json(本地硬上限)和 /etc/fleet/updater.json
└─ 启用 monitor-agent.service 和 fleet-updater.service
面板收到 OnEnrolled(Monitor 挂钩)
├─ public_host 未提供时,取注册请求的来源 IP
├─ 按“线路任务模板”为该 Agent 计算有效任务集(TaskSet)
└─ 通知 Probe(通过 monitor.probe.agents_changed)→ Probe 自动连接新 Agent
从安装到开始出数据,全程不需要手工配置
```
名称冲突、审批、接管、禁用等行为都采用 Fleet 的默认规则。
## 3. Probe 身份与 Agent 列表同步
Probe 不认识 Backend,它需要的 Agent 列表经由任意一个已连接的 Agent 获取。
```text
面板:POST /api/admin/probes {name}
└─ 生成 Fleet 节点身份,返回 probe.json(只能下载一次;轮换密钥 /rotate 会使旧密钥失效,吊销 /revoke 会让所有 Agent 断开它)
{ probe_id, private_key, bootstrap: [ {agent_id, host, tcp_port, spki}, ... ],
limits: { max_test_mbps, max_total_pps } } ← 本地硬上限,面板无法修改;在路由器上建议调低
Probe 启动
├─ 依次尝试 bootstrap 中的 Agent,与其中一个建立 Fleet 点对点会话(peer 用途签名)
├─ monitor.probe.agents ──> Agent ──> Backend
│ <── { version, agents: [ {agent_id, host, tcp_port, udp_ports, spki}... ] }
├─ 调和:新增的 Agent → 建立会话;被移除或禁用的 → 断开
└─ 之后列表的任何变化,都通过已连接的 Agent 推送 monitor.probe.agents_changed;
Probe 用 Fleet.Hosting.ConfigStore 把最新列表写回 bootstrap(这是配置,不是测量数据)
```
- 每个 Agent 通过自己的期望状态(`TaskSet.peers`)获得 Probe 的公钥,用来验证点对点会话的签名。
- 吊销 Probe:在面板上重新生成身份,旧公钥立即从所有 Agent 的期望状态中移除,旧会话随之断开。
## 4. Agent 本地配置(`/etc/monitor/agent.json`,面板无法修改)
```json
{
"fleet": { "server": "https://panel.example.com", "identity_dir": "/etc/monitor" },
"listen": { "control_port": 7443, "udp_ports": [7443], "tcp_ports": [7444] },
"limits": {
"max_total_mbps": 200,
"max_total_pps": 20000,
"allowed_target_cidrs": [],
"max_concurrent_tests": 1
},
"fleet_policy": { "allow_methods": ["monitor.test.run", "monitor.test.cancel", "monitor.probe.agents_changed"] }
}
```
- `limits` 是**本地硬上限**:期望任务集超出这些范围时,调和器拒绝执行,并在 `rejected[]` 中给出原因。
- `allowed_target_cidrs` 默认为空,即不允许执行任何目标任务;需要时由节点所有者在本机显式开启。
- `listen` 默认不包含 443。要用 443 测量,需要在本机把它加入 `udp_ports` 或 `tcp_ports`(端口不能被真实服务占用),见 [measurement.md](measurement.md) 第 8 节。
- `fleet_policy.allow_methods` 在 Fleet 默认值的基础上进一步收窄。
## 5. 相关 API
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| 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/POST/PATCH/DELETE | `/api/admin/probes`、`/probes/{id}` | Probe 身份的创建、列表、改名、删除 |
| POST | `/api/admin/probes/{id}/rotate`、`/revoke` | 轮换密钥、吊销 |
| POST | `/api/admin/agents/{id}/probes/{probe_id}/disconnect` | 让 Agent 断开某个 Probe |
| GET | `/install.sh`、`/install.ps1` | 安装脚本 |
## Agent 的本地配置:主机状态上报
`agent.json` 的 `reporting` 段(面板无法修改):
```json
{ "reporting": { "host_stats": true, "host_interval_s": 2 } }
```
`host_stats` 为 true(默认)时,Agent 每隔 `host_interval_s` 秒用 `monitor.host` 上报一份主机资源占用的汇总数字(CPU、内存、根分区、网卡累计流量与网速、运行时长;没有型号、主机名、IP);设为 false 就一个字也不上报。