节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
13.11 KiB
Stardust
# 星尘 Stardust 架构与权限审查报告 > 审查日期:2026-07-24 > 审查范围:Stardust 仓库全部工程(Stardust / Stardust.Data / Stardust.Extensions / Stardust.Server / Stardust.Web / Stardust.Web.Vue / StarAgent / DeployAgent / StarGateway / Plugins / SDK / 测试 / Doc) > 审查方式:只读代码核查,所有结论均基于代码事实与路径证据。 > 说明:本报告为分析产物,未修改任何项目源码;仅新增本文档。 --- ## 一、定位与现状对照 项目定位(AGENTS.md):NewLife.X 生态的轻量级分布式服务治理平台 = **配置中心 + 注册发现 + APM 监控 + 日志中心 + 远程发布 + 节点运维**,对标"轻量版 Nacos + 运维 Agent + 监控"。 代码成熟度:2993 commits,分层清晰,核心能力(配置/注册/追踪/指标/发布/Agent 守护/管理台/MCP)**主体已落地**,是可运行工程而非原型。 --- ## 二、分层架构与模块职责 | 层 | 工程 | 职责 | 关键入口/类 | |----|------|------|-------------| | 客户端 SDK | `Stardust/` | 配置拉取、注册发现、调用追踪、指标/日志上报 | `StarFactory`、`AppClient`(IRegistry)、`StarTracer`(ITracer)、`StarHttpConfigProvider`(IConfigProvider) | | ASP.NET 扩展 | `Stardust.Extensions/` | 管线接入中间件 | `AddStardust`/`UseStardust`/`RegisterService`、`TracerMiddleware` | | 数据层 | `Stardust.Data/` | XCode ORM 实体与统计任务,9 个 Model.xml、~70 表,按天分表+归档 | `Platform/Model.xml`、`StarDataHelper.SplitSqliteTables` | | 控制面 | `Stardust.Server/` | 注册/配置/发布/统计 API、指标聚合;无状态,状态全在 DB | `Node/Config/App/Deploy/Trace/Log/Gateway/OAuth` 控制器、`NodeStatService` 等 | | 管理台 | `Stardust.Web/`(Cube)+ `Stardust.Web.Vue/` | 管理与可视化 | Areas:Nodes/Registry/Configs/Deployment/Monitors/Redis/MySql/Gateway/Platform | | 边缘代理 | `StarAgent/` + `DeployAgent/` | 节点守护、进程生命周期、指标采集、心跳、指令执行、远程发布 | `StarService`(NewLife.Agent)、`CheckDog` 看门狗、`DeployService` | | 网关 | `StarGateway/` | HTTP 反向代理、负载均衡、TCP 健康检查、SSL、Admin API、WS 透传 | `HttpReverseProxy`、`ProxyServer` | | 插件 | `Plugins/`(NetworkDetect / AgentExpansion / MySqlAgent) | Agent 侧辅助能力 | 继承 `AgentPlugin`(Start/Stop) | | 多语言 SDK | `SDK/`(JS/Python/Go/PHP/ASP;Java 空白) | 异构语言接入 | 各语言 StardustClient/Tracer/Config | | 基础设施 | NewLife.Core / NewLife.Cube / XCode | 通用能力底座 | ClientBase、ObjectContainer、Membership、Entity<T> | > 架构分层可视化见 AGENTS.md 心智模型与下方"依赖关系"章节;核心依赖链:客户端/网关/Agent → Server(HTTP/WS)→ Data(XCode)→ 基础设施(Core/Cube/XCode)。 --- ## 三、模块间依赖关系 - **客户端 → Server**:`StarHttpConfigProvider`/`AppClient`/`StarTracer` 经 HTTP/WS 调用 Server 的 `Config/App/Trace` 接口;配置支持轮询 + `config/publish` 命令推送;服务发现结果缓存 `star_services.json` 并支持 `Bind` 变更回调。 - **Agent ↔ Server**:双通道——WebSocket 实时指令下发(`NodeSessionManager` 内存会话)+ HTTP 心跳拉取(`NodeCommand` 表 `AcquireCommands`)。 - **Web → Server/Data**:基于 Cube 的控制器直连 `Stardust.Data` 实体读写,无独立 BFF。 - **Gateway → Agent**:联动 StarAgent 做冷启动/空闲回收,并透传 WS;路由用静态 `GatewayRoute/GatewayNode` 表 + TCP 探测(非注册中心动态发现)。 - **Plugins ← StarAgent**:由 Agent 加载并事件驱动。 - **全栈 → 基础设施**:依赖 NewLife.Core(XTrace/ClientBase/ObjectContainer/Snowflake/缓存)、NewLife.Cube(权限/自动控制器)、XCode(ORM/分表)。 --- ## 四、功能完整性评估(对照定位) | 能力 | 完成度 | 说明 | |------|--------|------| | 配置中心 | 中 | 有版本/历史/灰度字段,但客户端只取快照,无强 `onChanged` 回调,无按比例灰度下发与客户端回滚 | | 注册发现 | 中 | RoundRobin+Weight+Tag/Scope 过滤;无熔断/限流;`HealthCheckHelper` 存在但消费端未主动剔除;无显式 Unregister,下线靠心跳超时 | | APM 追踪 | 中 | 自动 span + 服务端回写采样参数;但用**自有头、`traceparent` 被 Exclude,未用 W3C**,异构链路不互通 | | 指标监控 | 中 | 系统指标(CPU/内存/线程/句柄)齐全、分表聚合;**无自定义业务指标、无多维 Tag** | | 日志中心 | 良 | `AppClientLog` + `LogController` 接收 | | 远程发布 | 中 | Git→构建→打包→分发→解压守护;有 `ShadowDeployStrategy` 影子部署雏形,但**无一键回滚 / 灰度比例控制台编排** | | 节点运维 Agent | 良 | 守护/看门狗/采集/指令执行成熟 | | 管理控制台 | 良 | Cube 多 Area 覆盖,权限模型完整;告警仅钉钉/Webhook | | 网关 | 弱 | 反向代理+LB+健康检查,**无限流/熔断/鉴权/WAF** | | 多语言 SDK | 弱 | 普遍仅"配置+APM",**注册发现/指标/事件总线缺失,Java 空白** | | MCP 集成 | 中 | Token 资源授权 + 反射自动注册 27 个 Action + 审计 + 单测,已有管理面能力;但 SDK 侧无 MCP 客户端,文档落后代码 | --- ## 五、项目 ID 隔离与权限专题分析(重点) > 用户反馈:"项目 id 有的有有的没有,有的接口调用没有按照项目隔离,项目权限这块很不完善。" 本节量化核实。 ### 5.1 实体层 ProjectId 分布(Stardust.Data/**/Model.xml) **有 ProjectId 的表(约 15 张,~23%)**:App、AppOnline、Service(Entity);AppTracer、AlarmGroup(Monitors);AppConfig(Configs);AppDeploy、AppPipeline(Deployment);Node、NodeOnline(Nodes);MySqlNode、RedisNode;GatewayCluster、GatewayRoute;ProjectUser(Platform)。锚点表 `GalaxyProject` 自身用 `TenantId` 而非 ProjectId。 **缺 ProjectId 的表(约 49 张,量化风险)**: - Registry:`AppService`、`AppConsume`、`AppMeter`、`AppHistory`、`AppCommand`、`AppClientLog` - Monitors:`TraceItem`、`TraceRule`、`TraceData`、`SampleData`、`SampleData2`、`TraceDayStat`/`HourStat`/`MinuteStat`、`AppDayStat`/`MinuteStat`、`AlarmRecord`、`AlarmHistory` - Configs:`AppRule`、`AppQuote`、`ConfigData`、`ConfigHistory` - Deployment:`AppDeployNode`、`AppDeployVersion`、`AppDeployHistory`、`AppBuildNode`、`AppPipelineRun`/`Step`、`Attachment`、`SslCertificate` - Nodes:`NodeHistory`、`NodeData`、`NodeCommand`、`NodeVersion`、`NodeStat`、`NodeRule`、`NodeLocation`、`DomainProvider`、`ProductRelease`、`ProductPackage`、`DotNetPackage` - MySql/Redis:`MySqlData`、`RedisData`、`RedisMessageQueue`;Gateway:`GatewayNode`;Platform:`McpToken`、`McpTokenResource`、`McpAudit` **结论**:聚合根(应用/节点/部署集/项目)有 ProjectId,但其下所有明细与海量时序数据表(追踪、采样、统计、历史、服务实例、配置数据、部署节点/版本)均无 ProjectId,只能经 AppId/NodeId 间接关联,**无法在字段级过滤项目**。 ### 5.2 接口/控制器层隔离情况(Stardust.Web/Areas) **未按项目隔离的接口(证据)**: - `Registry/Controllers/AppServiceController.cs:40` Search 仅按 `appId/client/serviceId` 过滤,实体 AppService 无 ProjectId → 跨项目服务实例全可见。 - `Registry/Controllers/AppMeterController.cs:35`、`AppConsumeController`、`AppHistoryController`、`AppCommandController`、`AppClientLogController` 同上,均无 ProjectId 维度。 - `Monitors/Controllers/TraceDataController.cs:28`、SampleData/TraceDayStat 等 Search 仅按 `appId/itemId/clientId` 过滤,TraceData 无 ProjectId。 - `Deployment` 的 AppDeployNode/Version/History、`Monitors` 的 AlarmRecord/History 均无 ProjectId 字段,无法按项目过滤。 **即使有 ProjectId 的实体,过滤也是"opt-in"非强制**: - `Nodes/Controllers/NodeController.cs:141,160` 取 `p["projectId"]`,仅在 URL 带 projectId 时才过滤;直接访问 `/Nodes/Node` 无参即返回所有项目节点。 - `Registry/Controllers/AppController.cs:72,79`、`AppOnlineController.cs:74,80`、`AppConfigController`、`AppDeployController`、`AppTracerController` 等同理:projectId 来自查询参数,非全局强制。 **管理台项目上下文**:`Views/Shared/_Project_Nav.cshtml:7` 仅从 `Context.Request.Query["projectId"]` 读取并拼接到各列表链接(opt-in);`Stardust.Web.Vue` 中**无任何 projectId 处理**(grep 无匹配),Vue 前台无项目作用域概念。 ### 5.3 权限模型(基于 NewLife.Cube) - 仅见**功能级**注解 `[EntityAuthorize(PermissionFlags.X)]`(约 30 处,如 NodeController、AppController、TraceDataController 等),控制菜单/增删改查动作权限。 - **全库零处 `[DataPermission]`**(grep 确认),即无数据级行权限注解。 - `ProjectUser`(项目用户关系,`Platform/Model.xml:70`)仅由 `ProjectUserController.cs` 自身维护,**从未在任何业务查询中用于限制当前用户可看的项目** → 用户-项目绑定形同虚设,无数据级隔离。 - `GalaxyProject` 的 `TenantId` 同样未在控制器中做租户过滤。 ### 5.4 缺口清单 - **(a) 缺 ProjectId 的实体**:上述 ~49 张表,尤其所有时序/明细表。 - **(b) 未按项目隔离的接口**:所有无 ProjectId 实体对应的控制器(AppService/AppConsume/AppMeter/TraceData/SampleData/各 Stat/AlarmRecord/ConfigData/ConfigHistory/AppDeployNode 等)必然跨项目泄露;有 ProjectId 的控制器因 projectId 为可选参数,未强制时亦泄露。 - **(c) 权限缺口**:仅功能级(角色/菜单),无数据级项目隔离;ProjectUser 绑定未生效;无 `[DataPermission]`/全局查询过滤器;Vue 前台无项目作用域。 ### 5.5 改进建议(项目隔离与权限) 1. **统一 ProjectId 基线**:为 AppService、AppConsume、AppMeter、TraceData/SampleData/各 Stat、ConfigData/ConfigHistory、AppDeployNode/Version/History、AlarmRecord/History、GatewayNode、McpToken 等补 ProjectId(可由 AppId/NodeId 反填,参考 `FixDataHostedService.cs` 的回填逻辑)。 2. **查询自动注入项目作用域**:在 `Search(Pager p)` 基类或全局 ActionFilter 中,从当前用户经 ProjectUser 解析"可访问项目集合",对所有带 ProjectId 的查询强制 `ProjectId In (...)`;对无 ProjectId 的表通过 AppId/NodeId 子查询间接隔离。 3. **引入数据级权限**:采用 `[DataPermission]` 或重写 `EntityController` 的 `Search` 注入用户-项目白名单;用 `SetProject` 全局中间件代替当前 opt-in 的 URL 参数。 4. **Vue 前台补齐"当前项目"选择器**并让所有列表请求携带项目作用域,与管理台一致。 --- ## 六、总体改进建议(P0→P3) **P0(核心治理闭环 + 安全 + 数据隔离)** - 追踪切换/兼容 W3C `traceparent`,打通 OpenTelemetry 生态。 - Agent 指令加白名单/沙箱;核查并加固 `SendCommand` 鉴权;传输强制 TLS/mTLS。 - 落地 RedisStream(或等价)事件总线,消除单实例 `SessionManager` 瓶颈,支撑 Server 多实例水平扩展。 - **项目隔离基线 + 查询自动注入项目作用域 + 启用 `[DataPermission]`/全局过滤器,堵住跨项目数据泄露**(详见第五节)。 **P1(补齐多语言与网关,扩大覆盖面)** - 补齐 Java SDK;统一多语言 SDK 接口契约,补齐注册发现/指标/事件总线(至少 Python/Go 优先)。 - 网关增加限流/熔断/鉴权插件化 + 对接注册中心动态路由。 **P2(增强治理深度与运营能力)** - 配置:强 `onChanged` 回调 + 按比例灰度下发 + 客户端回滚。 - 服务发现:消费端主动健康检查剔除 + 显式 Unregister 优雅下线;可选熔断/限流。 - 指标:自定义业务指标 + 多维 Tag。 - 发布:一键回滚 + 灰度比例控制台编排。 - 告警:规则引擎 + 多渠道(邮件/短信/电话/Webhook)。 - 自身可观测性大盘。 **P3(工程与生态)** - 推进 Vue 前端替换 Razor(含项目作用域);补充真实业务 Samples 与跨语言测试。 - 文档刷新(MCP/网关/服务网格/CI/CD/安全),与代码对齐。 --- ## 七、结论 星尘已具备一个**可运行的轻量服务治理平台骨架**,核心链路基本打通,工程体量成熟。主要短板集中在三处:**异构生态接入(多语言 SDK 不对等 + 非 W3C 追踪 + 无服务网格)**、**横向扩展与实时性(单实例会话/事件总线未落地)**、**安全与深度治理能力(网关薄弱、指令 RCE、多租户弱、回滚/告警不足)**。 其中**项目 ID 隔离与权限是当前最突出、也最易被忽视的数据安全短板**:约 77% 的数据表无 ProjectId,绝大多数查询未强制按项目过滤,用户-项目绑定(ProjectUser)形同虚设,仅有功能级权限而无数据级隔离——在真实多租户场景下存在跨项目数据泄露风险。建议作为 P0 优先治理。 --- *本报告为只读审查产物,未修改任何项目源码,仅新增本文档。*