ci/woodpecker/push/main-amd64-build Pipeline was successful
- Group docs by category with an index (docs/README.md); fix every link, code comment and the protocol conformance test that read docs/protocol.md. - access.md and security.md rewritten to what is implemented: removed the unadopted member-proof chain, roles and recovery key that do not exist, the old implementation order and the budgets; gaps now carry a status. - enrollment, deployment, api: the install flow is the static, hash-checked script with environment variables; no default admin. - README and architecture: new topology and update-flow diagrams (operator passkey, CI signing, registry feed, auth and trust modules).
125 lines
11 KiB
Markdown
125 lines
11 KiB
Markdown
# MoShiro
|
||
|
||
MoShiro 是一个自托管的**网络线路质量观测工具**。它在若干 Probe(例如家宽出口)与多台 Agent(例如海外 VPS)之间做主动网络测量,只记录逐包、逐事件的原始数据;Backend 保存这些原始数据,推算延迟、丢包、抖动、吞吐等指标,并回答「如果在这条线路上部署某类服务,体验会怎样」;Web 界面用来查看、比较和管理。
|
||
|
||
## 项目边界
|
||
|
||
**它做什么**
|
||
|
||
- 主动测量:组合 TCP、UDP、TLS、ICMP 等采集积木,只记录时间、序号、大小这类原始事实,**不转发也不记录业务内容**。
|
||
- 线路分析:Backend 从原始数据生成时间序列指标,按服务模型(REALITY、Hysteria2、Minecraft 等)评分并对多条线路排序、对比;模型和指标可以事后重算。
|
||
- 管理:节点注册与审批、Probe 和 Agent 之间连哪些线路、任务与按需测试、节点版本与更新,都在管理端完成。
|
||
|
||
**它不做什么**
|
||
|
||
- **节点是纯采集器**:Agent 和 Probe 没有终端、命令执行、文件读写和自更新能力,也不加载外部代码。更新由节点宿主机上的更新器完成,节点进程只放面板转来的发布清单。
|
||
- **不是主机监控**:Agent 只上报 CPU、内存、磁盘、网卡流量和运行时长这类只读的汇总数字,不采集型号、主机名、进程和任何 IP;Probe 不上报主机资源。
|
||
- **不暴露地址**:公开接口里没有 IP、城市、ASN;国家和运营商只由 Backend 查询(节点自己不访问任何外部服务)。
|
||
- 暂不包含告警(见文末待办)。
|
||
|
||
## 信任关系
|
||
|
||
```text
|
||
管理员 ── 密码或 passkey(Cookie 会话 + CSRF),或 API 令牌(按能力授权)──▶ Backend
|
||
访客 ── 匿名只读,站点设为公开时才可用(没有 IP、城市、ASN)──────────────▶ Backend 公开接口
|
||
|
||
操作员 ── passkey 给「操作员集合」签名 ──▶ Backend 只转发 ──▶ 节点自己验链
|
||
(创世指纹和属主在安装时固定在节点上;集合里还登记了 Backend 的服务器密钥,节点据此认 Backend、加密链路)
|
||
节点 ── 加入令牌一次性注册,之后用自己的 ECDSA P-256 密钥签名认证 ───────▶ Backend(只存公钥)
|
||
Probe ── 先敲门,再用自己的密钥签名建立测量会话 ───────────────────────────▶ Agent(只放行面板名单里的 Probe 公钥)
|
||
CI ── 发布私钥对「镜像 digest 清单」签名 ──▶ 镜像仓库 / Backend ──▶ 节点宿主机的更新器用本机公钥验签
|
||
```
|
||
|
||
- **Backend 不信任节点上报的内容**:数据按线路隔离存放;节点的身份靠签名,数据库泄露也无法冒充节点。
|
||
- **节点不信任 Backend 的下发**:任务超出节点本机的硬上限(目标网段、码率、包速率、监听端口)就被拒绝;节点不执行任何「执行类」指令;改信任(操作员集合)要操作员 passkey 签名,Backend 伪造不了。
|
||
- **更新不依赖面板的诚实**:清单必须由发布私钥签名(面板登记时验一次,节点宿主机的更新器用本机公钥再验一次)、只认本机配置的镜像仓库、按 digest 拉取、拒绝旧的 `seq`。面板被攻破也推不出恶意镜像。可信的发布密钥由部署的人决定:官方 CI 密钥始终信任,也可以另外信任自己的公钥。
|
||
- **没有默认账户**:第一次打开管理端进认领向导,用后端日志里的认领码创建第一个管理员、注册 passkey、建立信任根。每个节点都必须有属主(passkey),由节点自己强制。
|
||
- 运行中的二进制不做校验(节点自报的哈希不可信);「资产是我们的」靠安装时的签名清单和签名的 `SHA256SUMS`。详见 [`docs/security/`](docs/security/security.md)。
|
||
|
||
## 架构
|
||
|
||
```text
|
||
操作员 passkey ──签名「操作员集合」──┐ CI 发布私钥 ──签名「镜像 digest 清单」──▶ 镜像仓库(清单 + 镜像)
|
||
▼ ▲
|
||
Web(展示端 · 管理端) │ 定时取清单
|
||
▲ REST + SSE │
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Backend(面板) │──────────────────────────────┘
|
||
│ Api · Auth(会话 · passkey · API 令牌 · 审计) │
|
||
│ Trust(操作员集合 · 服务器身份)· Registry · Planner · Links │
|
||
│ Releases(发布清单 · 可信发布密钥) │
|
||
│ Ingest · Analysis · LiveHub │
|
||
│ Store(段文件 + SQLite) │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
▲ ▲
|
||
│ wss 长连接(节点发起,应用层加密) │ wss 长连接(节点发起,应用层加密)
|
||
│ 任务、数据、状态、更新通知 │ 身份、Agent 列表、状态、更新通知
|
||
┌────────────────────┐ ┌──────────────────────┐
|
||
│ Agent × 10+ │ ◀── 测量会话 ── │ Probe × N │
|
||
│ 有公网 IP,监听 │ 先敲门再 TLS │ 家宽等出口,NAT 后 │
|
||
└────────────────────┘ └──────────────────────┘
|
||
测量会话:TLS 控制通道 + UDP/TCP 数据通道,由 Probe 主动拨出
|
||
宿主机更新器(容器节点):用本机公钥验签 → 按 digest 拉镜像 → 重启,失败回滚
|
||
```
|
||
|
||
两种连接:**Probe 和 Agent 都用长连接连 Backend**(身份、任务、状态、更新通知),**测量只走 Probe → Agent**(Probe 主动拨出,Agent 不需要连 Probe,家宽也不需要入站端口)。哪些 Probe 连哪些 Agent 由 Backend 决定:默认自动全连,也可以在管理端手动选择。
|
||
|
||
```text
|
||
采集(只记录) 传输(有界、至少一次) 分析(注册制、可重算) 展示
|
||
Probe / Agent 积木 ──▶ 原始列块(10 秒一块)──▶ Backend 段文件 ──▶ 指标与服务模型 ──▶ REST / SSE ──▶ Web
|
||
```
|
||
|
||
Backend 用段文件保存原始数据,用 SQLite 保存索引、指标与配置。**完整的架构、数据链路、安全边界和设计决策见 [`docs/design/architecture.md`](docs/design/architecture.md)。**
|
||
|
||
## 协议
|
||
|
||
- **控制链路(Fleet)**:节点到 Backend 的 `wss` 长连接(`/api/agent/v1/rpc`),JSON-RPC 2.0 信封加二进制通道;挑战加签名认证,`hello` 协商版本和能力,心跳;**期望状态同步**(Backend 下发完整快照,节点调和并回报已应用的版本和被拒绝的条目);**可靠发件箱**(原始块至少一次投递,按 id 去重)。Fleet 与业务无关,放在 `backend/fleet/`。
|
||
- **业务方法**:`moshiro.*`(按需测试、Probe 断开、事件、主机汇总、更新通知等),状态文档有 `task_set`(Agent 的任务集)和 `probe_agents`(Probe 的 Agent 列表)。
|
||
- **测量数据面**:Probe 到 Agent 的 TLS 控制通道、UDP 和 TCP 数据通道(默认 `7443/tcp`、`7443/udp`、`7444/tcp`);会话用 `session_id` 和 MAC 认证、不绑定五元组,NAT 映射变化后自动跟随。
|
||
- **REST + SSE**:`/api/public`(展示,可匿名)、`/api/admin`(管理);OpenAPI 在 `backend/openapi/v1.json`,前端据此生成类型。
|
||
|
||
细节见 [`docs/design/protocol.md`](docs/design/protocol.md)、[`backend/fleet/README.md`](backend/fleet/README.md)、[`docs/api/api.md`](docs/api/api.md)、[`docs/security/enrollment.md`](docs/security/enrollment.md)。
|
||
|
||
## 如何构建
|
||
|
||
环境:.NET SDK 10(`global.json` 指定版本)、Node.js 与 npm。在仓库根目录:
|
||
|
||
```sh
|
||
dotnet build MoShiro.slnx -c Release # Backend、Agent、Probe、Fleet、测试和 CI 工具
|
||
npm ci --prefix web && npm run build --prefix web # 展示端和管理端,产物在 web/display/dist、web/admin/dist
|
||
```
|
||
|
||
本地运行:先在 `backend/` 里 `dotnet run --project src/MoShiro.Backend -- --urls http://localhost:5000`,再 `npm run dev --prefix web`,展示端是 <http://localhost:5173/>,管理端是 <http://localhost:5173/admin/>。第一次打开管理端会进认领向导,认领码在后端日志里(或用 `MoShiro__ClaimCode` 指定)。
|
||
|
||
测试和检查:
|
||
|
||
```sh
|
||
dotnet test --solution MoShiro.slnx # 后端和节点的测试
|
||
npm run lint:css --prefix web # 前端样式(颜色只能写在主题令牌里)
|
||
npm run gen:api --prefix web # 后端改了接口之后重新生成前端类型
|
||
```
|
||
|
||
Backend、Agent、Probe 以 OCI 镜像发布(Linux amd64、arm64),Agent 和 Probe 另有 Linux glibc/musl、macOS、Windows 的二进制包。NativeAOT 的构建细节、CI 触发规则(`[CI]`、`[SKIP TESTS]`、版本 tag)、镜像路径、容器节点的运行和更新见 [`docs/ops/deployment.md`](docs/ops/deployment.md);前端见 [`web/README.md`](web/README.md),后端见 [`backend/README.md`](backend/README.md)。
|
||
|
||
## 文档
|
||
|
||
| 文档 | 内容 |
|
||
| --- | --- |
|
||
| [`docs/README.md`](docs/README.md) | 文档索引,按类别组织 |
|
||
| [`docs/design/`](docs/design/architecture.md) | 设计:架构与决策、线协议、存储与查询、采集与分析 |
|
||
| [`docs/security/`](docs/security/security.md) | 安全:零信任与威胁模型、访问控制与入网信任链、注册与身份 |
|
||
| [`docs/api/`](docs/api/api.md) | 接口:端点说明、API 规范 |
|
||
| [`docs/ops/deployment.md`](docs/ops/deployment.md) | 运维:构建、发布、CI、部署与更新 |
|
||
| [`docs/dev/`](docs/dev/project-layout.md) | 开发:仓库结构与依赖规则、代码风格 |
|
||
| [`backend/fleet/README.md`](backend/fleet/README.md) | Fleet 节点框架(身份、注册、连接) |
|
||
|
||
代码目录:`backend/`(Backend、`fleet/` 节点框架、`shared/` 测量引擎和协议、`agent/`、`probe/`、`tests/`)、`web/`(`display` 展示端、`admin` 管理端、`shared`)、`packaging/` 和 `scripts/`(部署与维护)、`ci/` 和 `.woodpecker/`(流水线)。
|
||
|
||
## 待办
|
||
|
||
见 [`TODO.md`](TODO.md)。
|
||
|
||
## 许可证
|
||
|
||
本项目采用 [Apache License 2.0](LICENSE)。
|