diff --git a/README.md b/README.md index 3d5c731..da70858 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,36 @@ # MoShiro -MoShiro 是一个自托管的网络线路质量观测工具。它在 Probe 与多个 Agent 之间执行主动网络测量,记录逐包和逐事件结果;Backend 保存原始数据并生成可查询的线路指标,Web 界面用于查看、比较和管理节点。 +MoShiro 是一个自托管的**网络线路质量观测工具**。它在若干 Probe(例如家宽出口)与多台 Agent(例如海外 VPS)之间做主动网络测量,只记录逐包、逐事件的原始数据;Backend 保存这些原始数据,推算延迟、丢包、抖动、吞吐等指标,并回答「如果在这条线路上部署某类服务,体验会怎样」;Web 界面用来查看、比较和管理。 -它面向需要比较不同网络出口、评估线路稳定性,或观察特定网络服务体验的场景。Agent 与 Probe 专注于测量和上报;它们不提供远程终端、命令执行或文件管理能力。 +## 项目边界 -## 能力概览 +**它做什么** -- **主动测量**:组合 TCP、UDP 等测量模块,采集延迟、丢包、抖动、吞吐和连接事件。 -- **线路分析**:从原始测量数据生成时间序列指标,并比较线路在不同服务模型下的体验。 -- **节点管理**:通过 Fleet 节点框架处理身份、注册、连接、任务同步和数据上报。 -- **实时面板**:展示端查看线路状态和历史趋势;管理端负责节点、任务和系统配置。 -- **线路管理**:Backend 决定哪些 Probe 连哪些 Agent(自动连接开关加手动选择),在管理端的线路矩阵里一键开关。 -- **节点信息与更新**:节点自报系统、架构和构建信息(版本、tag、提交、构建时间),国家和运营商由 Backend 查询;容器节点的更新由 CI 签名、Backend 转发、节点宿主机上的更新器验签并执行,失败自动回滚,管理端可以看状态和点「更新」。 -- **自托管**:Backend 使用段文件和 SQLite 保存数据;提供 Linux、systemd 和 OpenWrt 相关部署文件。 +- 主动测量:组合 TCP、UDP、TLS、ICMP 等采集积木,只记录时间、序号、大小这类原始事实,**不转发也不记录业务内容**。 +- 线路分析:Backend 从原始数据生成时间序列指标,按服务模型(REALITY、Hysteria2、Minecraft 等)评分并对多条线路排序、对比;模型和指标可以事后重算。 +- 管理:节点注册与审批、Probe 和 Agent 之间连哪些线路、任务与按需测试、节点版本与更新,都在管理端完成。 + +**它不做什么** + +- **节点是纯采集器**:Agent 和 Probe 没有终端、命令执行、文件读写和自更新能力,也不加载外部代码。更新由节点宿主机上的更新器完成,节点进程只放面板转来的发布清单。 +- **不是主机监控**:Agent 只上报 CPU、内存、磁盘、网卡流量和运行时长这类只读的汇总数字,不采集型号、主机名、进程和任何 IP;Probe 不上报主机资源。 +- **不暴露地址**:公开接口里没有 IP、城市、ASN;国家和运营商只由 Backend 查询(节点自己不访问任何外部服务)。 +- 暂不包含告警(见文末待办)。 + +## 信任关系 + +```text + 管理员 ── 账号密码(Cookie 会话 + CSRF)或 API 令牌(read · admin · release)──▶ Backend + 访客 ── 匿名只读,站点设为公开时才可用(没有 IP、城市、ASN)──────────────▶ Backend 公开接口 + + 节点 ── 加入令牌一次性注册,之后用自己的 ECDSA P-256 密钥签名认证 ───────▶ Backend(只存公钥) + Probe ── 用同一把密钥签名建立测量会话 ───────────────────────────────────▶ Agent(只放行面板名单里的 Probe 公钥) + CI ── 发布私钥对「镜像 digest 清单」签名 ──▶ Backend 原样转发 ──▶ 节点宿主机的更新器用本机公钥验签 +``` + +- **Backend 不信任节点上报的内容**:数据按线路隔离存放;节点的身份靠签名,数据库泄露也无法冒充节点。 +- **节点不信任 Backend 的下发**:任务超出节点本机的硬上限(目标网段、码率、包速率、监听端口)就被拒绝;节点不执行任何「执行类」指令。 +- **更新不依赖面板的诚实**:清单必须由发布私钥签名;节点宿主机的更新器用本机公钥验签、只认本机配置的镜像仓库、按 digest 拉取、拒绝旧的 `seq`。面板被攻破也推不出恶意镜像。 ## 架构 @@ -35,99 +53,68 @@ MoShiro 是一个自托管的网络线路质量观测工具。它在 Probe 与 测量会话:TLS 控制通道 + UDP/TCP 数据通道,由 Probe 主动拨出 ``` -两种连接:**Probe 和 Agent 都用长连接连 Backend**(身份、任务、状态、更新通知),**测量只走 Probe → Agent**(Probe 主动拨出,不需要入站端口)。哪些 Probe 连哪些 Agent 由 Backend 决定:默认自动全连,也可以在管理端手动选择。数据存储:段文件保存原始数据,SQLite 保存索引、指标与配置。 +两种连接:**Probe 和 Agent 都用长连接连 Backend**(身份、任务、状态、更新通知),**测量只走 Probe → Agent**(Probe 主动拨出,Agent 不需要连 Probe,家宽也不需要入站端口)。哪些 Probe 连哪些 Agent 由 Backend 决定:默认自动全连,也可以在管理端手动选择。 -## 快速开始 - -### 环境要求 -- .NET SDK 10;项目使用 `global.json` 指定 SDK 版本和滚动策略。 -- Node.js 与 npm,用于构建 Web 前端。 - -### 构建 - -从仓库根目录构建全部 .NET 项目(Backend、Agent、Probe、Fleet、测试和 CI 工具): - -```sh -dotnet build MoShiro.slnx -c Release +```text + 采集(只记录) 传输(有界、至少一次) 分析(注册制、可重算) 展示 + Probe / Agent 积木 ──▶ 原始列块(10 秒一块)──▶ Backend 段文件 ──▶ 指标与服务模型 ──▶ REST / SSE ──▶ Web ``` -NuGet 包版本统一在根目录 `Directory.Packages.props` 管理,项目中的 `PackageReference` 不写版本号。AotAnywhere 的 MSBuild SDK 版本在根目录 `global.json` 的 `msbuild-sdks` 中管理。`backend/MoShiro.slnx` 保留用于只构建后端目录内的项目。 +Backend 用段文件保存原始数据,用 SQLite 保存索引、指标与配置。**完整的架构、数据链路、安全边界和设计决策见 [`docs/architecture.md`](docs/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/protocol.md`](docs/protocol.md)、[`docs/fleet/link.md`](docs/fleet/link.md)、[`docs/api.md`](docs/api.md)、[`docs/enrollment.md`](docs/enrollment.md)。 + +## 如何构建 + +环境:.NET SDK 10(`global.json` 指定版本)、Node.js 与 npm。在仓库根目录: ```sh -npm ci --prefix web -npm run build --prefix web -npm run gen:api --prefix web # API schema changed after Backend edits -npm run lint:css --prefix web +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 ``` -前端产物位于 `web/display/dist/` 和 `web/admin/dist/`。NativeAOT 目标平台和 Windows 上使用 AotAnywhere 交叉构建的说明见 [`docs/deployment.md`](docs/deployment.md)。 +本地运行:先在 `backend/` 里 `dotnet run --project src/MoShiro.Backend -- --urls http://localhost:5000`,再 `npm run dev --prefix web`,展示端是 ,管理端是 。 -Backend、Agent 和 Probe 均以 OCI 镜像发布,支持 Linux/amd64 与 Linux/arm64;Agent 和 Probe 另外提供 Linux glibc/musl、macOS 与 Windows 二进制包。容器部署配置见 [`compose.yaml`](compose.yaml),发布说明见 [`docs/deployment.md`](docs/deployment.md)。 - -### 本地运行 - -1. **启动 Backend。** 在仓库根目录运行: +测试和检查: ```sh -cd backend -dotnet run --project src/MoShiro.Backend -- --urls http://localhost:5000 +dotnet test --solution MoShiro.slnx # 后端和节点的测试 +npm run lint:css --prefix web # 前端样式(颜色只能写在主题令牌里) +npm run gen:api --prefix web # 后端改了接口之后重新生成前端类型 ``` -2. **启动前端。** 保持 Backend 运行,在另一个终端的仓库根目录运行: +Backend、Agent、Probe 以 OCI 镜像发布(Linux amd64、arm64),Agent 和 Probe 另有 Linux glibc/musl、macOS、Windows 的二进制包。NativeAOT 的构建细节、CI 触发规则(`[CI]`、`[SKIP TESTS]`、版本 tag)、镜像路径、容器节点的运行和更新见 [`docs/deployment.md`](docs/deployment.md);前端见 [`web/README.md`](web/README.md),后端见 [`backend/README.md`](backend/README.md)。 -```sh -npm ci --prefix web -npm run dev --prefix web -``` +## 文档 -打开 使用展示端,或访问 进入管理端。依赖安装和前端配置见 [`web/README.md`](web/README.md);Backend 的首次启动与配置见 [`backend/README.md`](backend/README.md)。 - -### CI 构建规则 - -- Pull request 和 `dev` 分支 push:先跑 Backend tests,通过后再构建前端。 -- 在需要跳过 Backend tests 的提交信息后加 `[SKIP TESTS]`;Gitea pull request 需要把标记写进 PR 标题。前端构建仍会运行。 -- `main` 上的提交信息包含 `[CI]` 时,并行构建 Backend、Agent、Probe 的 Linux/amd64 镜像,推送到 Zot 的 `moshiro-dev/` 仓库;普通 main push 不构建。 -- 推送 `vMAJOR.MINOR.PATCH` tag 会触发全平台正式构建和 Release 发布。 - -完整触发条件、开发镜像标签和发布路径见 [`docs/deployment.md`](docs/deployment.md)。 - -## 项目布局 - -| 路径 | 说明 | +| 文档 | 内容 | | --- | --- | -| [`backend/`](backend/README.md) | Backend 服务、Fleet 框架、共享测量代码与 .NET 测试 | -| [`backend/agent/`](backend/agent/README.md) | Agent 节点:注册到 Backend,接受 Probe 测量并上报数据 | -| [`backend/probe/`](backend/probe/README.md) | Probe 节点:发起线路测量并将采集数据交给 Agent | -| `backend/fleet/` | 可复用的节点身份、注册和连接框架 | -| `backend/shared/` | 测量引擎、协议和原始数据格式 | -| `web/display/`、`web/admin/` | 展示端和管理端 | -| `web/shared/` | 前端 API、图表、组件与主题 | -| `packaging/`、`scripts/` | 部署、构建与维护脚本 | -| `docs/` | [架构](docs/architecture.md)、[测量模型](docs/measurement.md)、[API](docs/api.md)、[部署](docs/deployment.md)等文档 | +| [`docs/architecture.md`](docs/architecture.md) | 架构、数据链路、安全边界、设计决策 | +| [`docs/protocol.md`](docs/protocol.md)、[`docs/fleet/`](docs/fleet/overview.md) | 线协议、Fleet 节点框架(身份、连接、更新) | +| [`docs/enrollment.md`](docs/enrollment.md) | 注册、身份、Probe 与 Agent 的接入 | +| [`docs/measurement.md`](docs/measurement.md)、[`docs/analysis.md`](docs/analysis.md) | 采集引擎与任务模型、分析层与指标 | +| [`docs/storage.md`](docs/storage.md)、[`docs/query.md`](docs/query.md) | 存储、展示数据查询 | +| [`docs/api.md`](docs/api.md)、[`docs/api-guidelines.md`](docs/api-guidelines.md) | API 规范与约束 | +| [`docs/deployment.md`](docs/deployment.md) | 构建、发布、CI、部署与更新 | +| [`docs/project-layout.md`](docs/project-layout.md)、[`docs/coding-style.md`](docs/coding-style.md) | 仓库结构与依赖规则、代码风格 | + +代码目录:`backend/`(Backend、`fleet/` 节点框架、`shared/` 测量引擎和协议、`agent/`、`probe/`、`tests/`)、`web/`(`display` 展示端、`admin` 管理端、`shared`)、`packaging/` 和 `scripts/`(部署与维护)、`ci/` 和 `.woodpecker/`(流水线)。 ## 待办 -已实现的能力见上面的概览和 `docs/`;还没做的: - -- **纯二进制节点的更新**:`fleet-updater`、`fleet-release`、Windows 服务和 OpenWrt(procd)适配器;设计见 [`docs/fleet/update.md`](docs/fleet/update.md)。容器节点(Agent、Probe)的签名发布和宿主机更新已经实现,见 [`docs/deployment.md`](docs/deployment.md)。 +- **纯二进制节点的更新**:`fleet-updater`、`fleet-release`、Windows 服务和 OpenWrt(procd)适配器;设计见 [`docs/fleet/update.md`](docs/fleet/update.md)。容器节点的签名发布和宿主机更新已经实现。 - **更新的灰度和自动策略**:按标签分批发布;`POLICY=auto` 的线上验证;后端自身的更新。 - **OpenWrt 打包**:procd 脚本、ipk/apk 包、sysupgrade 保留列表,在 aarch64 路由器上长时间运行验证。 - **安全加固**:对 UDP 包、控制帧、RawChunk、JSON-RPC 做模糊测试;伪造签名和重放的专项测试。 - **以后**:告警(Webhook)、真实 QUIC 握手积木、pcap/eBPF 采集。 -## 测试 - -```sh -dotnet test --solution MoShiro.slnx -``` - -```sh -# 前端样式检查(仓库根目录) -npm run lint:css --prefix web -``` - ## 许可证 本项目采用 [Apache License 2.0](LICENSE)。