From c07ad7ac39c3cb7f562fe0a2b30c30f510f47499 Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Mon, 10 Aug 2026 01:27:48 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=E6=9E=B6=E6=9E=84/?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=96=87=E6=A1=A3=E4=B8=8E=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=AF=84=E4=BC=B0=E8=B5=84=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/ARCHITECTURE.md: 系统架构说明 - docs/MODULES.md: 模块清单与职责 - docs/blackbird_project_profile.md: 项目画像 - docs/blackbird_project_evaluation.md: 项目评估 - docs/reports/fsys_public_frontend_research_20260810.md: fsys 公开前端调研 --- docs/ARCHITECTURE.md | 252 ++++++++++++ docs/MODULES.md | 89 +++++ docs/blackbird_project_evaluation.md | 37 ++ docs/blackbird_project_profile.md | 372 ++++++++++++++++++ .../fsys_public_frontend_research_20260810.md | 141 +++++++ 5 files changed, 891 insertions(+) create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/MODULES.md create mode 100644 docs/blackbird_project_evaluation.md create mode 100644 docs/blackbird_project_profile.md create mode 100644 docs/reports/fsys_public_frontend_research_20260810.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..12df0af --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,252 @@ +# Blackbird 架构文档(UniServe Framework) + +> 权威架构参考。本文以 `core/init.txt`(实际运行清单)与 `git HEAD` 为事实来源。 +> 与根目录 `README.md` 的偏差见文末「§10 与 README 的偏差」。 +> 最后核对于:2026-08-10。 + +--- + +## 1. 文档目的与范围 + +Blackbird 是一套 **进程托管式轻量微服务** 系统(自研 UniServe Framework),用于支撑一个带内容审核的社区/笔记类 Web 应用及其周边 AI/嵌入式子系统。本文描述: + +- 系统上下文与边界 +- 部署拓扑(容器级) +- 关键请求链路 +- 服务清单(含语言、端口、职责、当前状态) +- 共享基础库与横切关注点 +- 关键架构决策(ADR 摘要) +- 演进策略与已知漂移 + +**不在本文范围**:单模块内部算法、前端页面细节、硬件机器人/帧缓冲子系统的实现。 + +--- + +## 2. 系统上下文(System Context) + +``` + 浏览器 / 客户端 + │ HTTPS :443 + ▼ + ┌─────────────────────────────────────────────────────────────┐ + │ Blackbird 系统边界 │ + │ waf → ca → gateway → {fsys, dnfs2, core} │ + │ 内部:db2 / ai_review / smtp / captcha2 / core(confs) │ + │ 独立:aibox(+BotOps) / bot4cj / lci │ + └─────────────────────────────────────────────────────────────┘ + │ pymsg/TCP (内部 RPC) │ SMTP (外部邮件) + ▼ ▼ + db2 / ai_review / smtp 邮件服务商 (注册验证码) +``` + +**参与者**: +- 终端用户:经 `:443` 访问社区首页、登录/注册、树状笔记。 +- 运维/开发者:经 `core:5200` 管理接口启停子进程。 +- 外部依赖:SMTP 邮件服务商(注册验证码)、DeepSeek API(ai_review)。 + +--- + +## 3. 部署拓扑(Container Diagram) + +``` + ┌──────────────────────────────────────────────────┐ + │ core (PMC / Nidus) │ + │ 进程托管 :5200 (HTTP 管理) + 内嵌 confs :8010 │ + │ 读 init.txt 拉起并守护下列子进程 │ + └───────────────────────┬──────────────────────────┘ + │ 启动 / 守护 + ┌────────────────┬───────────────────────┼──────────────────┬─────────────────┐ + ▼ ▼ ▼ ▼ ▼ + ┌────────────┐ ┌────────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ + │ redirect80 │ │ waf │ │ ca │ │ gateway │ │ fsys │ + │ :80 │ │ :443 │ │ :8443 │ │ :8445 │ │ :9200 │ + │ Python │ │ Go │ │ C++20 │ │ C++20 │ │ C++20 │ + └─────┬──────┘ └─────┬──────┘ └─────▲─────┘ └─────▲─────┘ └─────▲─────┘ + │ 301/308 │ TLS+coraza │ auth+forward │ loopback │ proxy + └───────────────►│ │ │ pure-fwd │ notes + └────────────────────►│ │ └────┬────┘ + │ │ │ pymsg + ┌────────┴────────┐ ┌─────┴────────┐ ┌────────▼─────┐ + │ dnfs2 :8006 │ │ core :5200 │ │ dnfs2 :8006 │ + │ C++20 │ │ (管理/守护) │ │ (经 fsys 代理)│ + └───────▲────────┘ └──────────────┘ └──────────────┘ + │ pymsg + ┌────────────┼─────────────┐ + ▼ ▼ ▼ + ┌────────────┐ ┌───────────┐ ┌───────────┐ + │ db2 :8005 │ │ai_review │ │ smtp │ + │ C++20 pymsg│ │ :8007 Py │ │ :8008 Py │ + │ +Logs 表 │ │ RAG+LLM │ │ pymsg │ + └─────▲──────┘ └─────▲─────┘ └─────▲─────┘ + │ │ 审核 │ 发码 + │ └─────────────┘ + ┌─────┴──────────────────────────────┐ + │ captcha2 :8009 (C++20, pymsg) │ + └─────────────────────────────────────┘ + + 独立 / 外设(不在主链路): + aibox :8765 (Python WebSocket, 独立产品) + BotOps (aibox 的 TUI 前端) + bot4cj (Cangjie + 树莓派 I2C, 硬件) + lci (C++ /dev/fb0, 嵌入式 GUI) + actpred / memdb / libtry (实验 / 支撑库) + + 日志链路: 各服务 log_client ──pymsg──► db2:8005 Logs 表 (fail-safe, db 不可用时静默丢弃) + 配置链路: core 内嵌 confs :8010 ──pymsg get──► 各服务 (confs/configs/*.ini, mtime 自动重载) +``` + +> 注:`core` 启动参数为 `./nidus.out -i init.txt --serve 5200 --confs 8010`,`--confs` 启用内嵌配置服务(由 confs2 合并而来,与 Python confs 协议兼容)。 + +--- + +## 4. 关键请求链路 + +### 4.1 正常访问(已登录) +1. 客户端若以 HTTP 访问 `:80`,`redirect80` 重定向到 HTTPS `:443`(GET/HEAD→301,其余→308 保留 body)。 +2. 请求打到 `waf:443`(Go/coraza):终止 TLS,运行 SecLang 规则;命中→403。 +3. 未命中规则 → 明文 HTTP 转发到 `ca:8443`,注入 `X-Forwarded-For` / `X-Forwarded-Proto`。 +4. `ca` 验签 Token,注入 `X-Auth-User` / `X-Auth-Admin`,转发到 `gateway:8445`(仅 loopback)。 +5. `gateway` 检查:显式 `Target-Url` 必须带 `X-Auth-User`(否则 401),且必须在 `Proxy.opened` 白名单(否则 403);转发到 `fsys:9200` / `dnfs2:8006` / `core:5200`。 +6. `fsys` 处理前端资源,笔记类请求代理到 `dnfs2:8006`。 + +### 4.2 注册 / 登录(ca 负责) +- `/login`、`/register`、`/reset_*`、`/captcha/image`、`/whoami` 由 `ca:8443` 直接处理(不再经 gateway 鉴权层)。 +- 密码:PBKDF2-HMAC-SHA256(10 万轮 + 16B 随机盐),常数时间比较。 +- Token:`Base64(payload) + "_" + RSA-Sign(payload)`,默认 1h 过期;RSA 密钥内存生成,重启即全失效;jti 黑名单 + 用户版本号双轨吊销。 +- 注册邮件验证码:ca 经 pymsg/TCP 调 `smtp:8008` 发送与校验;登录强制 CAPTCHA(`captcha2:8009`)。 +- 用户数据:ca 经 pymsg/TCP 调 `db2:8005` 存取(`Users` 表,首位注册者即管理员)。 +- 速率限制:登录 5/5min、注册 3/10min、发码 IP+邮箱双窗口,按 `X-Forwarded-For` 计数。 + +### 4.3 笔记写入(含内容审核) +`fsys → dnfs2:8006` → 新增节点前 `dnfs2` 调 `ai_review:8007 /review`(fail-closed,异常一律拦截)→ 审核通过后经 pymsg 调 `db2:8005 execute` 持久化。 + +### 4.4 日志 / 配置(横切) +- 各服务内置 `log_client`(异步队列 + 后台批量 flush)→ pymsg 写 `db2:8005` 的 `Logs` 表;`db2` 自带 30 天/100 万条清理线程。 +- 各服务启动时经 pymsg `get` 从 `core:8010` 拉取自身 `.ini`;`confs/configs/` 下 mtime 变化自动重载;环境变量覆盖;命令行参数最高优先级。 + +--- + +## 5. 服务清单(当前事实状态) + +| 服务 | 语言 | 端口 | 绑定 | 职责 | 状态 | +|------|------|------|------|------|------| +| **core** | C++20 | 5200 / 8010 | 5200 管理 / 8010 loopback | 进程托管(PMC) + 内嵌 confs 配置服务 | 生产 | +| **redirect80** | Python | 80 | 0.0.0.0 | HTTP→HTTPS 重定向 | 生产 | +| **waf** | Go | 443 | 0.0.0.0 | 边缘网关:TLS 终止 + coraza WAF | 生产 | +| **ca** | C++20 | 8443 | 127.0.0.1 | 中央认证 + 身份头注入 + 前置转发 | 生产 (v1.0.0) | +| **gateway** | C++20 | 8445 | 127.0.0.1 | 纯转发反向代理(loopback 强制自检) | 生产 (v0.9.0) | +| **fsys** | C++20 | 9200 | 127.0.0.1 | 前端托管 + dnfs 代理(static 的 C++ 重写) | 生产 | +| **dnfs2** | C++20 | 8006 | 127.0.0.1 | 树状笔记 CRUD | 生产(dnfs 的 C++ 重写) | +| **db2** | C++20 | 8005 | 127.0.0.1 | 通用 DB(pymsg execute) + 日志汇聚 | 生产(db 的 C++ 重写) | +| **ai_review** | Python | 8007 | 127.0.0.1 | AI 内容审核(DeepSeek + ChromaDB RAG) | 生产 | +| **smtp** | Python | 8008 | 127.0.0.1 | 邮件验证码后端(pymsg) | 生产(smtp3 C++ 重写待上线) | +| **captcha2** | C++20 | 8009 | 127.0.0.1 | 图形验证码(pymsg) | 生产(captcha 的 C++ 重写) | +| **aibox** | Python | 8765 | 127.0.0.1 | 独立 AI 智能体(WebSocket) | 独立产品 | +| **BotOps** | Python | — | — | aibox 的 TUI 前端 | 独立 | +| **bot4cj** | Cangjie | — | 树莓派 I2C | 机器人脚本解析器 | 独立硬件 | +| **lci** | C++ | — | /dev/fb0 | 嵌入式帧缓冲 GUI | 独立硬件 | +| **actpred** | Python | — | — | ML 预训练/推理 | 实验 | +| **memdb** | C++20 | — | — | 内存数据库 | 实验/支撑 | +| **libtry** | C | — | — | 嵌入式脚本解释器 | 支撑 | + +### 已被替代、不应再部署的遗留模块(不在 init.txt) +| 遗留 | 替代 | 说明 | +|------|------|------| +| `static` (Python) | `fsys` | 前端托管已 C++ 重写 | +| `db` (Python) | `db2` | DB 服务已 C++ 重写 | +| `dnfs` (Python) | `dnfs2` | 笔记服务已 C++ 重写 | +| `captcha` (Python) | `captcha2` | 验证码已 C++ 重写 | +| `confs` (Python) | 并入 `core` | 配置服务内嵌进 core(ConfsTask) | +| `smtp3` (C++) | (预备) | 代码就绪,init.txt 仍用 Python `smtp`,尚未平替 | + +--- + +## 6. 共享基础库 + +| 库 | 语言 | 说明 | +|----|------|------| +| libth | C++20 | 线程 / 条件变量 / FSM / 任务接口 | +| libhttp | C++20 | HTTP/WebSocket(Boost.Beast,服务端 + 客户端) | +| libcrypt | C++20 | AES_CBC / RSA / SHA256 / Base64 | +| libsqlite3 | C++20 | SQLite3 header-only 封装 | +| libmsg | C++20 | pymsg 协议 C++ 实现(4B 大端长度前缀 + UTF-8 JSON),与 Python pymsg 字节级兼容,提供 RpcClient/RpcServer/AsyncQueue | +| libtry | C | 嵌入式脚本解释器(递归下降,中文标识符) | +| pymsg | Python | 自研 RPC 基础库(`[4B 大端长度][UTF-8 JSON]`),Python 侧 db/log_client 依赖 | + +**协议约定**:内部 RPC 统一用 pymsg(TCP 长度前缀帧 + JSON);对外 HTTP;ca↔gateway 之间为明文 HTTP(TLS 已由 waf 终止)。 + +--- + +## 7. 横切关注点 + +### 7.1 安全分层(纵深防御) +- **边缘**:`waf` 终止 TLS + coraza 规则(本地自定义 100000–199999 / OWASP CRS 900000–999999),命中即 403。 +- **应用层**:`ca` 负责鉴权(PBKDF2 + RSA Token + CAPTCHA + 速率限制);`gateway` 仅 loopback,身份完全信任 ca 注入头。 +- **网络隔离**:`db2/ai_review/smtp/captcha2/confs` 仅监听 loopback,不经 gateway 直访(`Proxy.closed`)。 +- **fail-closed 文化**:`ai_review` 异常即拦截;`dnfs2` Token 验签失败返 503;`gateway` 错误响应脱敏;SMTP 内部错误对外统一通用码(如 3103)。 + +### 7.2 可观测性 +- 集中式日志:所有服务经 `log_client` 异步写 `db2` 的 `Logs` 表(service/level/message/trace_id/extra)。 +- **缺口**:无分布式追踪(trace_id 仅记录未串联)、无指标/监控中间件、无告警。 + +### 7.3 配置管理 +- `core` 内嵌 confs(`:8010`)统一分发 `confs/configs/*.ini`;内存缓存 + mtime 重载;路径遍历防护。 +- 三层覆盖:confs 默认值 → 环境变量 → 命令行参数。 + +### 7.4 弹性 / 容错 +- 启动顺序敏感:`core` 拉起顺序为 db2→ai_review→dnfs2→smtp→fsys→waf→ca→gateway→captcha2→aibox→redirect80;pymsg 客户端带 `retry_on_refused` 等依赖就绪。 +- 日志 fail-safe:db2 不可用时静默丢弃,不影响业务。 +- 有状态单点:`smtp` / `captcha2` 验证码存进程内存,**不支持多实例水平扩展**(需换 Redis 才能扩)。 + +--- + +## 8. 关键架构决策(ADR 摘要) + +**ADR-1|认证从 gateway 剥离为独立 ca 模块(v0.9.0 / ca v1.0.0)** +- 背景:gateway 同时承担鉴权与转发,职责过重、RSA 密钥与业务逻辑耦合。 +- 决策:ca 独立负责 Token 签发/验签、登录/注册/限流/CAPTCHA,gateway 退居 `127.0.0.1:8445` 纯转发。 +- 后果:+1 网络跳数;ca 成为安全边界(loopback + strip-then-set);gateway 不再依赖 libcrypt/OpenSSL。 + +**ADR-2|核心服务 C++20 重写(db→db2, dnfs→dnfs2, static→fsys, captcha→captcha2, confs→core;smtp3 就绪)** +- 背景:Python 服务依赖 venv/pip/Flask,且部分存在 P0/P1 安全问题。 +- 决策:用 libhttp+libmsg+boost 重写,接口字节级兼容(pymsg/HTTP 路由不变),可平替。 +- 后果:去掉 Python 运行时依赖、修复安全缺陷、提升吞吐;过渡期需双版本并存维护;ai_review/aibox/smtp/redirect80 仍保留 Python。 + +**ADR-3|confs 配置服务内嵌进 core** +- 背景:独立 confs 进程增加编排复杂度。 +- 决策:confs2 合并为 `core` 的 `ConfsTask`,由 `--confs ` 启用。 +- 后果:少一个守护进程;core 略微变重;配置协议与目录结构不变。 + +**ADR-4|pymsg 作为内部 RPC 标准** +- 决策:内部数据访问统一 `[4B 大端长度][UTF-8 JSON]` over TCP,C++/Python 双实现字节级兼容。 +- 后果:业务服务不直接连数据库,数据访问层解耦;引入轻量自研协议(无现成生态)。 + +--- + +## 9. 演进策略与已知缺口 + +- **无服务注册发现 / 容器编排**:服务地址在 `waf/config.yaml` 与 `gateway` 的 `Proxy.*` 中静态配置,由 `core` 进程托管。适合个人/中小规模 DIY,但扩展需手工。 +- **smtp3 待上线**:C++ 重写已完成并通过安全审计,但 init.txt 仍指向 Python `smtp`,建议择机平替以消除最后一块 Python 有状态服务。 +- **可观测性缺口**:缺 tracing/metrics/告警,建议后续引入轻量方案(或复用 db2 Logs + 定时聚合)。 +- **水平扩展限制**:smtp/captcha 内存态为单点,若需多实例需引入 Redis 等共享存储。 + +--- + +## 10. 与 README.md 的偏差(待同步) + +以下为本文相对于根 `README.md` 的纠正点,建议择机回填 README: + +1. **端口**:README 端口表写 `gateway 8443`,实际 `ca:8443`、`gateway:8445`(v0.9.0 起)。README 正文已正确,仅端口表需改。 +2. **前端模块**:README 仍列 `static`(Python)为主,实际生产为 `fsys`(C++ 重写),`static` 已废弃。 +3. **C++ 重写版未进主表**:README 模块表仍以 `db`/`dnfs`/`captcha`/`confs` 为主,实际生产跑 `db2`/`dnfs2`/`captcha2`,`confs` 已并入 `core`。 +4. **init.txt 不含 confs**:独立 confs 服务已不用,配置由 `core --confs 8010` 内嵌提供。 +5. **fsys README 图示滞后**:`fsys/README.md` 架构图仍写 `gateway :8443`,应为 `ca:8443 → gateway:8445`。 +6. **工作记忆偏差**:项目记忆中的 `gateway:8443 → fsys / dnfs` 与 `confs:8010` 需更新为 `ca:8443 → gateway:8445`、`dnfs2`、confs 内嵌 core。 + +--- + +## 11. 文档管理约定(遵循既有规则) + +- 全局架构文档置于 `docs/`(本文件)。 +- 模块细节写在各模块目录 `README.md`。 +- 审计/审查/报告类文档分别入 `docs/security`、`docs/reviews`、`docs/reports`。 diff --git a/docs/MODULES.md b/docs/MODULES.md new file mode 100644 index 0000000..1ff1952 --- /dev/null +++ b/docs/MODULES.md @@ -0,0 +1,89 @@ +# 模块清单(blackbird / micro_servers) + +> 一套 DIY 的轻量级「进程托管式微服务」(UniServe Framework)。 +> 混合语言:C++20(core/gateway/dnfs2/db2/lib*)、Python(fsys/dnfs/db/ai_review/smtp/captcha/confs/redirect80/BotOps/aibox/actpred/pymsg)、Go(waf)、仓颉/Cangjie(bot4cj)。 +> 由 `core` 读 `init.txt` 拉起并守护各子进程;`waf:443 → gateway:8443 → 业务服务` 为对外主链路。 + +## 一、核心与编排 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| core | C++20 | 5200 | 进程托管服务 PMC / Nidus,读 `init.txt` 拉起守护子进程,提供 HTTP 管理接口(`--send/--exec/--list/--kill/--serve`) | + +## 二、入口与网关层 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| redirect80 | Python | 80 | HTTP→HTTPS 重定向(GET/HEAD 301,其余 308 保留 body);纯标准库 `http.server` | +| waf | Go | 443 | 唯一对外入口,终止 TLS + coraza 规则匹配(SecLang)+ 反代到 gateway;`kill -HUP` 热加载;规则库 `waf/rules/` | +| gateway | C++20 | 8443 | 应用层网关(内部 HTTP),注册/登录鉴权、PBKDF2 密码哈希、RSA Token 签发校验、Cookie 认证、速率限制、反向代理(`Proxy.opened` 白名单) | + +## 三、业务服务(对外,经 gateway 代理) + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| fsys | Python/Flask | 9200 | 前端托管(社区首页/静态页面/媒体流/文件浏览);**原为 static,2026-08 重命名为 fsys**(core/init.txt 已同步),过渡期仍保留 legacy `static/` 目录存放 `fsys.py` | +| dnfs | Python/Flask | 8006 | 树状菜单(Dendrachy Network File-System),基于 pid 的节点树 CRUD,新增节点前调 ai_review 审核 | +| dnfs2 | C++20 | 8006 | dnfs 的 C++20 重实现(libhttp + libmsg),接口兼容可平替,修复 P0/P1(fail-closed 验签/所有权校验/脱敏) | +| ai_review | Python/Flask | 8007 | AI 内容审核,DeepSeek + ChromaDB RAG(色情/违禁药/赌博/诈骗/仇恨暴力),fail-closed 宁可误拦 | + +## 四、基础设施 / 支撑服务(仅内部调用) + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| db | Python/pymsg | 8005 | 通用数据库服务,SQL-over-TCP(SQLAlchemy Core 参数化防注入),内置集中式日志(Logs 表 + 自动清理) | +| db2 | C++20 | 8005 | db 的 C++20 重实现(libmsg + boost::json + libsqlite3),`execute` 路由/where 语法/响应格式对齐,可平替 | +| confs | Python/pymsg | 8010 | 统一配置分发,集中存放各服务配置(`confs/configs/`),内存缓存 + mtime 自动重载,路径遍历防护 | +| smtp | Python/pymsg | 8008 | 邮件服务,注册邮箱验证码后端(路由 send_email/verify_email/health),6 位码内存存储、冷却/限流/熔断 | +| captcha | Python/pymsg | 8009 | 验证码服务,图形验证码(一次性、5 分钟过期),经 gateway `GET /captcha/image` 代理给浏览器 | + +## 五、AI 智能体与前端 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| aibox | Python | 8765 | 独立 AI 智能体系统(DeepSeek + WebSocket),自带技能系统/记忆/任务调度/前端与语音客户端 | +| BotOps | Python/Textual | — | aibox 的终端 TUI 前端,WebSocket 连接 aibox,Markdown 增量流式渲染、思考模式、任务侧栏、自动重连 | +| actpred | Python/PyTorch | — | 动作预测(图像 + 动作历史 → 预测下一个动作),bot4cj 的「大脑」配套;支持从 `.mt` 脚本预训练 | + +## 六、机器人硬件与嵌入式 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| bot4cj | 仓颉/Cangjie | — (树莓派 I2C) | 机器人硬件脚本解析器,解析 `.mt` 驱动 PCA9685 舵机 / MPU6050 陀螺仪 / 扬声器,面向 Dashun 蜘蛛机器人 | +| lci | C++ | — (/dev/fb0) | 嵌入式帧缓冲图形界面(无需 X11/Wayland),矢量 GB2312 中文字库、图片渲染、实时数据可视化 | +| 3d | — (资产) | — | 机器人 / 机械臂 CAD 模型(STEP/STL/SLDPRT),bot4cj 配套硬件资产 | + +## 七、共享基础库 + +| 模块 | 语言 | 说明 | +|------|------|------| +| libth | C++ | 线程库:`Thread`、`Cv_wait`、`Fsm`、`ITask` | +| libhttp | C++ | HTTP/WebSocket 库(Boost.Beast):`HttpServer`(含 WS 服务/代理)、`HttpClient`(含 WS 客户端) | +| libcrypt | C++ | 加密库:`AES_CBC`、`MyRSA`、`SHA256`、`Base64`、`Crypto_Basic` | +| libsqlite3 | C++ | SQLite3 header-only 封装 | +| libmsg | C++ | pymsg 协议 C++ 实现(4B 大端长度前缀 + UTF-8 载荷),`MsgClient/Server`、`RpcClient/Server`、`AsyncQueue`,与 Python pymsg 字节级兼容 | +| libtry | C | 嵌入式脚本解释器(~741 行),手写递归下降,支持中文标识符,用于嵌入式操作界面 shell | +| pymsg | Python | 自研 RPC 基础库(`[4B 长度][UTF-8 JSON]`),db 服务端与各 `log_client.py` 的基础依赖(setuptools 包) | +| memdb | C++ | 内存数据库(include/src),内部组件,未在主 README 模块表列出 | + +## 八、测试与文档 + +| 模块 | 说明 | +|------|------| +| tests | 黑盒测试套件(`test_db_*`/`test_gateway_*`/`test_waf_*`/`test_dnfs_*`),子进程 + HTTP 验证,前后自动备份恢复 db | +| docs | 文档聚合(security/ 审计、reviews/ 审查、reports/ 分析、INDEX.md),41+ 篇 md | + +## 九、根级构建与部署脚本 + +- `_inst.sh`:一键按依赖顺序构建安装(库先行,core 最后) +- `_setup.deb.sh` / `_setup.rhel.sh`:系统依赖安装(Debian/Ubuntu、RHEL 系) +- `docker.sh` / `docker-compose.yml`:容器化部署 +- 部署路径约定 `/opt/micro_servers/`,`core` 的 `init.txt` 即从该路径拉起其余服务 + +## 关键链路速记 + +- **请求主链路**:client → `redirect80`(:80→443) → `waf`(:443 TLS + WAF) → `gateway`(:8443 鉴权) → `fsys`(:9200) / `dnfs`(:8006) +- **日志链路**:各服务 `log_client.py`(异步批量)→ `db:8005` Logs 表(fail-safe,db 不可用时静默丢弃) +- **配置链路**:业务服务 → `confs:8010`(内存缓存 + mtime 重载,confs 不可用时回退本地配置) +- **数据/审核/邮件**:`dnfs` → `db:8005`(pymsg 持久化);`dnfs` → `ai_review:8007`(审核);注册邮件 `gateway` → `smtp:8008` +- **端口一览**:80 redirect80 · 443 waf · 8443 gateway · 5200 core · 9200 fsys · 8006 dnfs/dnfs2 · 8005 db/db2 · 8007 ai_review · 8009 captcha · 8008 smtp · 8010 confs · 8765 aibox diff --git a/docs/blackbird_project_evaluation.md b/docs/blackbird_project_evaluation.md new file mode 100644 index 0000000..9655d44 --- /dev/null +++ b/docs/blackbird_project_evaluation.md @@ -0,0 +1,37 @@ +# Blackbird / micro_servers 项目红队评估 + +> 评估对象:`docs/blackbird_project_profile.md`(2026-08-10 advisory 整合稿) +> 评估视角:材料红队(事实 / 推断 / 未知 + 矛盾与缺证) +> 评估时间:2026-08-10 + +## 一句话结论 +架构主张清晰、文档可审计性极高的自托管轻量微服务框架;但"安全评级 A-"缺乏代码级实证,3 项高危整改全部处于 `human_review_pending`,当前不适合暴露于多租户或不可信内网。 + +## 优势(已确认事实) +- **定位成立**:砍掉 K8s 的服务注册/编排/消息总线,保留微服务拆分与统一入口收益,自托管 + MIT,价值主张自洽。 +- **可审计性远超同类个人项目**:41+ 篇安全/分析文档 + 24 篇逐模块审计报告,风险闭环有基底。 +- **协议基石扎实**:pymsg/libmsg 字节级兼容的 `[4B 长度][UTF-8 JSON]` 帧,支撑 v1/v2 双栈平滑迁移。 +- **认证设计不弱**:PBKDF2 10 万轮、常数时间比较、RSA 签名 Token、Cookie 安全属性、fail-closed 边界。 + +## 关键风险(矛盾与缺证) +1. **评级名实不符**:称"B+→A-",但 3 高危(WAF 失效 / core root RCE / 内部零信任缺失)均未核实修复。A- 更像目标而非现状。 +2. **WAF 实际不拦截**:定位"唯一对外入口 + coraza",但 `waf/rules/local/custom.conf` 的 6 条 SecRule 全被注释、无 `crs/` 目录 → 实际仅 TLS 终止 + 响应头,SQLi/XSS/命令注入零防护。 +3. **core 本地 root RCE**:`parse_data_from_mq` 对 list/kill/exec 未鉴权即经 `/bin/sh -c` 执行,且 core 以 root 运行。这是致命项却被标 `human_review_pending`。 +4. **内部零信任缺失**:pymsg 无握手/无鉴权/明文无 TLS,db `execute` 接受任意 action/table/where,完全依赖 127.0.0.1 隔离。 +5. **端口口径漂移**:MODULES.md 记 gateway:8443,README 记 8445,未同步。 +6. **密钥变量静默失效**:`.env.example` 写 `OPENAI_API_KEY`,代码读 `DEEPSEEK_API_KEY`。 +7. **质量债**:v1/v2 双实现(db/db2、dnfs/dnfs2、pymsg/libmsg…)并存,无单元测试、无 CI(无 `.github/workflows`),回归与语义漂移风险高。 +8. **部署半成品**:docker-compose 仅纳 3 服务,生产以 systemd 为准——容器化链路不完整。 + +## 缺证项(需人工复核) +- 3 高危是否在 2026-08-08 之后的提交中已修复(研究报告基于快照,文档未给代码证据)。 +- docker-compose 补全状态、MODULES.md 端口同步状态。 + +## 优先级建议(收口路径) +- P0:启用 WAF 规则 + 补 `crs/`(直击高危 1)。 +- P0:core MQ 落地 `verify_admin_token` 并降权运行(直击高危 2)。 +- P1:内部服务加调用方鉴权 / pymsg 上 mTLS 或 Unix socket(直击高危 3)。 +- P2:ai_review `/review` 加鉴权 + 结构化提示词;统一 `DEEPSEEK_API_KEY`;引入单元测试与 CI;双实现收口单轨。 + +## 成熟度判定 +**个人/小团队可信内网自用 = 可用;暴露公网或多租户 = 不建议。** 文档完备度是亮点,代码整改完成度与测试覆盖是短板。 diff --git a/docs/blackbird_project_profile.md b/docs/blackbird_project_profile.md new file mode 100644 index 0000000..76453b4 --- /dev/null +++ b/docs/blackbird_project_profile.md @@ -0,0 +1,372 @@ +# Blackbird / micro_servers 项目资料长文档 + +> 文档类型:项目资料 / 综合参考手册(面向开发者、维护者、审计者与潜在贡献者) +> 资料来源:仓库主 `README.md`、各模块 `README.md`、`docs/INDEX.md`、`docs/MODULES.md`、`docs/security/*`、`docs/reviews/*`、`docs/reports/blackbird_research_report.md`、`docs/security/SECURITY_HARDENING_PLAN_20260803.md`、`docs/blackbird_promo_pack.md` +> 整理日期:2026-08-10 +> 文档状态:`advisory`(基于仓库现有文档整合;涉及最新代码整改状态的部分标注为 `human_review_pending`,需结合代码人工复核) + +--- + +## 0. 文档说明 + +本文档将 Blackbird(仓库名 `micro_servers`,框架名 **UniServe Framework**)过去分散在 40+ 篇说明、审计与报告中的信息,整合为一份可按章节查阅的项目资料。 + +- **事实边界**:所有模块职责、端口、协议描述以主 `README.md`(2026-08-10 口径,已含 `ca` 中央认证模块)为准;安全发现以 `blackbird_research_report.md`(2026-08-08 快照)与 `docs/security/` 逐模块审计为准。 +- **口径差异提醒**:`docs/MODULES.md` 仍记 `gateway:8443`,属 `ca` 认证前置化之前的旧口径;当前拓扑为 `waf:443 → ca:8443 → gateway:8445`,以主 `README.md` 为准。 +- **质量状态约定**:基于文档推断与整合的结论标记为 `advisory`;涉及"代码是否已修复某高危项"的判断标记为 `human_review_pending`,因其需对照最新提交逐文件核验。 + +--- + +## 1. 项目概述 + +### 1.1 一句话定位 + +Blackbird 是一套 **DIY 的轻量级"进程托管式微服务"框架**,用 C++20 / Python / Go / 仓颉(Cangjie) 混合实现,让个人与中小团队用一台服务器、一个脚本,拥有「安全入口 + 统一鉴权 + 数据库 + AI 审核 + 业务功能」的完整能力,免去 Kubernetes 等重型基础设施的复杂度。 + +### 1.2 设计哲学与核心主张 + +- **能力拆分但重量极轻**:保留微服务"拆分、统一入口、安全分层、可观测"的真正收益,砍掉服务注册发现、容器编排、消息总线等重型组件。 +- **你完全掌控**:数据自托管、代码 MIT 开源,不绑定任何云厂商。 +- **多语言自由组合**:核心用 C++(性能/系统),胶水与业务用 Python(效率),边缘网关用 Go(coraza 生态),硬件控制用仓颉(树莓派)。 +- **进程托管式编排**:一个 `core` 进程当"保姆",读 `init.txt` 拉起并守护所有子服务。 + +### 1.3 适用对象 + +| 群体 | 诉求 | Blackbird 的契合点 | +|------|------|-------------------| +| 独立开发者 / 个人站长 | 不想被运维压垮 | 一键脚本 + systemd,对外只记一个域名 | +| 中小团队 | 可控、低成本内部中台 | 不依赖外部 SaaS,数据握在自己手里 | +| 注重数据主权者 | 数据绝不能出本机 | 全程自托管,MIT 可改 | +| AI / 硬件爱好者 | 想玩智能体、嵌入式舵机 | aibox 智能体 + bot4cj 舵机 + lci 帧缓冲界面 | + +### 1.4 与云原生微服务的差异 + +未引入服务注册发现、容器编排、消息总线;服务地址在 `waf/config.yaml` 与 `gateway` 配置中静态配置。对于个人/中小规模 DIY 场景,这种取舍在简洁性与可控性上合理,但也意味着横向扩展需自行演进。 + +### 1.5 许可证与归属 + +各模块均采用 **MIT License**(详见各目录 `LICENSE`)。项目由个人开发者「qing」维护,仓库地址 `https://git.cancerai.top/qing/blackbird`。 + +--- + +## 2. 架构总览 + +### 2.1 UniServe 架构定义 + +以 `core`(C++20)为统一宿主进程,读取 `init.txt` 并经 shell 拉起多语言微服务。各服务通过内部 HTTP 对外暴露业务能力,通过 `pymsg/TCP`(自研 RPC)做数据访问与日志汇聚。 + +### 2.2 当前拓扑(含 ca 认证前置化) + +``` + ┌──────────────────────────────────────────────┐ + │ core (PMC / Nidus) │ + │ 进程托管服务 · 监听 :5200 (HTTP 管理接口) │ + │ 读取 init.txt 拉起并守护下列子进程 │ + └───────────────┬──────────────────────────────┘ + │ 启动 / 守护 + ┌──────────────┬──────────────┼──────────────┬──────────────────┬──────────────┐ + ▼ ▼ ▼ ▼ ▼ ▼ + ┌──────────────┐ ┌─────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ + │ redirect80 │ │ waf │ │ ca │ │ gateway │ │ fsys │ │ dnfs │ + │ :80 重定向 │ │ :443 入口│ │ :8443 认证│ │ :8445 纯转发 │ │ :9200 前端 │ │ :8006 树状 │ + └──────────────┘ └────┬────┘ └────┬─────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ + │ TLS终止 │ 鉴权+前置 │ 反向代理 │ 代理笔记 │ pymsg + │ coraza │ 转发 │ (loopback) │ │ + └──────────┴─────►───────┴──────────────────┴─────────────────┘ + 认证链路(v0.9.0 起): waf:443 ──HTTP──► ca:8443 (认证+前置转发) ──HTTP──► gateway:8445 (纯转发, 仅 loopback) ──► 内部服务 + 日志链路: 各服务 ──(log_client, pymsg)──► db:8005 (Logs 表,fail-safe 静默丢弃) + 配置链路: 业务服务 ──(pymsg get)──► confs:8010(mtime 自动重载) +``` + +> `db2` / `dnfs2` 分别是 `db` / `dnfs` 的 C++20 重实现,架构位置与 Python 版一致,接口兼容可平替。`BotOps`、`lci`、`bot4cj` 不在主图中(终端前端 / 帧缓冲界面 / 树莓派硬件,不联网)。 + +### 2.3 core 进程托管模型 + +- 可执行文件 `nidus.out`,以 systemd 单元 `Nidus.service` 常驻(崩溃守护由 systemd 负责,core 自身不含自动重启逻辑)。 +- 两种模式:命令行子系统(`--send/--exec/--list/--kill`)与 HTTP 伺服器(`--serve `)。 +- 经命名管道(Pipe)与消息队列(Mq)实现进程间通信;读 `init.txt` 自启动列表,按行拉起 ai_review / db / dnfs / smtp / static / waf / ca / gateway / captcha / aibox。 + +### 2.4 请求链路(8 步) + +1. 客户端以 HTTP 访问 `:80`,由 `redirect80` 重定向到 HTTPS `:443`(GET/HEAD 301,其余 308 保留 body)。 +2. 所有请求先打到 `waf:443`,终止 TLS、运行 coraza 规则,命中即 403。 +3. 未命中请求以明文 HTTP 转发到 `ca:8443`,透传 `X-Forwarded-For` / `X-Forwarded-Proto`。 +4. `ca` 对 `/login`、`/register` 做账号鉴权(PBKDF2 + RSA Token + 可选 CAPTCHA + 速率限制;注册经 pymsg/TCP 调 `smtp:8008` 发码),用户数据走 `db:8005`。 +5. 其余请求携带 Token,经 `ca` 验签后注入 `X-Auth-User` 转发到 `gateway:8445`(仅 loopback,仅做存在性检查),再由 gateway 反代到 `Proxy.opened` 放开的内部服务(`fsys:9200` / `dnfs:8006`)。 +6. `db:8005` 与 `ai_review:8007` 在 `Proxy.closed` 中,仅允许内部调用。 +7. `dnfs` 处理节点 CRUD 时经 pymsg/TCP 调 `db` 持久化,新增节点前调 `ai_review` 审核。 +8. 各服务经 `log_client.py` 异步批量推送日志到 `db` 的 `Logs` 表(fail-safe)。 + +### 2.5 端口一览 + +| 端口 | 服务 | 绑定 | 说明 | +|------|------|------|------| +| 80 | redirect80 | 0.0.0.0 | HTTP→HTTPS 重定向 | +| 443 | waf | 0.0.0.0 | HTTPS 对外入口(TLS + coraza) | +| 8443 | ca | 127.0.0.1 | 中央认证(内部 HTTP) | +| 8445 | gateway | 127.0.0.1 | 纯转发反代(loopback) | +| 5200 | core | 127.0.0.1 | PMC HTTP 管理接口 | +| 9200 | fsys | 127.0.0.1 | 前端托管(经 gateway 代理) | +| 8006 | dnfs/dnfs2 | 127.0.0.1 | 树状菜单(经 gateway 代理) | +| 8005 | db/db2 | 127.0.0.1 | 数据库服务(pymsg/TCP) | +| 8007 | ai_review | 127.0.0.1 | AI 审核(仅内部调用) | +| 8009 | captcha | 127.0.0.1 | 验证码(经 gateway 代理) | +| 8008 | smtp | 127.0.0.1 | 邮件服务(仅内部调用) | +| 8010 | confs | 127.0.0.1 | 统一配置(pymsg/TCP) | +| 8765 | aibox | 127.0.0.1 | AI 智能体(WebSocket,独立产品) | + +--- + +## 3. 模块清单(按职责分组) + +### 3.1 核心与编排 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **core** | C++20 | 5200 | 进程托管服务 PMC/Nidus,读 `init.txt` 拉起守护子进程,提供 HTTP 管理接口(`--send/--exec/--list/--kill/--serve`) | + +核心设计:systemd 常驻、root 运行(见第 5 章风险)、Pipe/Mq 进程通信、无内置看门狗(崩溃自愈依赖 systemd)。 + +### 3.2 入口与网关层 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **redirect80** | Python | 80 | HTTP→HTTPS 重定向(GET/HEAD 301 / 其余 308),纯标准库 | +| **waf** | Go | 443 | 唯一对外入口,终止 TLS + coraza 规则匹配(SecLang)+ 反代到 ca;`kill -HUP` 热加载;规则库 `waf/rules/` | +| **ca** | C++20 | 8443 | 中央认证服务(v1.0.0,内部 HTTP),注册/登录鉴权、Token 签发校验、身份头注入后前置转发到 gateway | +| **gateway** | C++20 | 8445 | 应用层网关(v0.9.0,仅 loopback),纯转发反代,不验签(认证已迁至 ca) | + +**ca 关键设计**:PBKDF2-HMAC-SHA256(10 万轮 + 16 字节盐)、常数时间比较防 timing attack;Token 为 `Base64(payload)+"_"+RSA-Sign(payload)`,默认 1 小时过期,RSA 密钥启动时内存生成(重启即失效);`HttpOnly+Secure+SameSite=Lax` 的 `q4_token` Cookie;登录 5 次/5 分钟、注册 3 次/10 分钟速率限制;首位注册者即管理员(无默认管理员账号)。 + +**gateway 关键点**:纯转发,存在性不变量——显式 `Target-Url` 请求必须携带 ca 注入的 `X-Auth-User`,缺失一律 401;`Target-Url` 必须在 `Proxy.opened` 白名单。 + +### 3.3 业务服务(对外,经 gateway 代理) + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **fsys**(原 static) | Python/Flask | 9200 | 前端托管:社区首页/静态页/媒体流/文件浏览;**2026-08 由 static 重命名为 fsys**(core/init.txt 已同步),过渡期仍保留 legacy `static/` 目录 | +| **dnfs** | Python/Flask | 8006 | 树状菜单(Dendrachy Network File-System),基于 pid 的节点树 CRUD,新增节点前调 ai_review 审核 | +| **dnfs2** | C++20 | 8006 | dnfs 的 C++20 重实现(libhttp + libmsg),接口完全兼容,修复 P0/P1(fail-closed 验签/所有权校验/脱敏) | +| **ai_review** | Python/Flask | 8007 | AI 内容审核,DeepSeek + ChromaDB RAG(色情/违禁药/赌博/诈骗/仇恨暴力),fail-closed 宁可误拦 | + +### 3.4 基础设施 / 支撑服务(仅内部调用) + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **db** | Python/pymsg | 8005 | 通用数据库服务,SQL-over-TCP(SQLAlchemy Core 参数化防注入),内置集中式日志(Logs 表 + 自动清理) | +| **db2** | C++20 | 8005 | db 的 C++20 重实现(libmsg + boost::json + libsqlite3),`execute` 路由/where 语法/响应格式对齐,可平替 | +| **confs** | Python/pymsg | 8010 | 统一配置分发,集中存放各服务配置(`confs/configs/`),内存缓存 + mtime 自动重载,路径遍历防护 | +| **smtp** | Python/pymsg | 8008 | 邮件服务,注册邮箱验证码后端(send_email/verify_email/health),6 位码内存存储、冷却/限流/熔断 | +| **captcha** | Python/pymsg | 8009 | 验证码服务,图形验证码(一次性、5 分钟过期),经 ca 的 `GET /captcha/image` 代理给浏览器 | + +### 3.5 AI 智能体与前端 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **aibox** | Python | 8765 | 独立 AI 智能体系统(DeepSeek + WebSocket),自带技能系统/记忆/任务调度/前端与语音客户端;由 core 拉起但与主干微服务无调用关系 | +| **BotOps** | Python/Textual | — | aibox 的终端 TUI 前端,WebSocket 连接 aibox,Markdown 增量流式渲染、思考模式、任务侧栏、自动重连 | +| **actpred** | Python/PyTorch | — | 动作预测(图像 + 动作历史 → 预测下一个动作),bot4cj 的「大脑」配套;支持从 `.mt` 脚本预训练 | + +### 3.6 机器人硬件与嵌入式 + +| 模块 | 语言 | 端口 | 职责 | +|------|------|------|------| +| **bot4cj** | 仓颉/Cangjie | — (树莓派 I2C) | 机器人硬件脚本解析器,解析 `.mt` 驱动 PCA9685 舵机 / MPU6050 陀螺仪 / 扬声器,面向 Dashun 蜘蛛机器人 | +| **lci** | C++ | — (/dev/fb0) | 嵌入式帧缓冲图形界面(无需 X11/Wayland),矢量 GB2312 中文字库、图片渲染、实时数据可视化 | +| **3d** | — (资产) | — | 机器人 / 机械臂 CAD 模型(STEP/STL/SLDPRT),bot4cj 配套硬件资产 | + +### 3.7 共享基础库 + +| 库 | 语言 | 说明 | +|----|------|------| +| **libth** | C++ | 线程库:`Thread`、`Cv_wait`、`Fsm`、`ITask` | +| **libhttp** | C++ | HTTP/WebSocket 库(Boost.Beast):`HttpServer`(含 WS 服务/代理)、`HttpClient`(含 WS 客户端) | +| **libcrypt** | C++ | 加密库:`AES_CBC`、`MyRSA`、`SHA256`、`Base64`、`Crypto_Basic` | +| **libsqlite3** | C++ | SQLite3 header-only 封装 | +| **libmsg** | C++ | pymsg 协议 C++ 实现(4B 大端长度前缀 + UTF-8 载荷),`MsgClient/Server`、`RpcClient/Server`、`AsyncQueue`,与 Python pymsg 字节级兼容 | +| **libtry** | C | 嵌入式脚本解释器(~741 行),手写递归下降,支持中文标识符,用于嵌入式操作界面 shell | +| **pymsg** | Python | 自研 RPC 基础库(`[4B 长度][UTF-8 JSON]`),db 服务端与各 `log_client.py` 的基础依赖(setuptools 包) | +| **memdb** | C++ | 内存数据库(internal 组件,未在主 README 模块表列出) | + +### 3.8 测试与文档 + +| 项 | 说明 | +|----|------| +| **tests** | 黑盒测试套件(`test_db_*`/`test_gateway_*`/`test_waf_*`/`test_dnfs_*`),子进程 + HTTP 验证,前后自动备份恢复 db | +| **docs** | 文档聚合(security/ 审计、reviews/ 审查、reports/ 分析、INDEX.md),41+ 篇 md | + +--- + +## 4. 通信协议:pymsg / libmsg + +这是 Blackbird 异构架构的通信基石。 + +- **帧结构**:`[4 字节大端长度][UTF-8 JSON]`,单帧上限 **64 MiB**。 +- **跨语言一致**:Python `pymsg` 与 C++ `libmsg` 字节级兼容,是 v1/v2 双栈迁移的关键支撑。 +- **资源防护**:慢连接总 deadline 防护 + 有界线程池,控制资源耗尽类风险。 +- **错误脱敏**:`_sanitize_error` 以正则替换绝对路径,降低信息泄露面。 +- **安全现状(重要)**:协议**无握手、无鉴权、明文无 TLS**,安全性完全依赖 `127.0.0.1` 主机隔离。一旦内网隔离被突破(同机多租户或某内部服务失陷),所有跨进程调用即暴露。详见第 5 章与加固计划。 + +--- + +## 5. 安全体系 + +### 5.1 边界鉴权优势(已达 A-) + +gateway(及 ca)的边界鉴权设计扎实,安全评级由 **B+ 提升至 A-**(Gateway v0.8.0 修复 P0:错误消息脱敏、SIGTERM 退出、doAccept 无限递归、8 秒关闭超时): + +- 口令:PBKDF2-HMAC-SHA256(10 万轮 + 16 字节盐),常数时间比较防时序攻击。 +- Token:RSA-2048 + PKCS#1 v1.5 签名,双轨吊销(jti 黑名单 + 用户版本号)。 +- 多层防护:CAPTCHA 一次性、登录 5/300s、注册 3/600s、邮箱级双窗口限流。 +- Cookie:`HttpOnly;Secure;SameSite=Lax`。 +- 管理面 fail-closed:`core` HTTP 接口绑 127.0.0.1 且 `verify_admin_token`。 + +### 5.2 已核实缺口(来自 2026-08-08 研究报告的审计结论) + +> 以下结论基于研究报告对当时代码快照的核实,整理时(2026-08-10)部分项已在 `ca` 引入、C++ 重写潮与加固计划中进入整改。**具体是否已在最新提交修复,需逐文件人工复核,状态标记为 `human_review_pending`。** + +| 级别 | 缺口 | 说明 | 关联整改 | +|------|------|------|----------| +| 高危 1 | WAF 规则失效 | `waf/rules/local/custom.conf` 的 6 条 SecRule 全部被注释,无 `crs/` 目录 → WAF 仅做 TLS 终止 + 响应头,不拦截 SQLi/XSS/命令注入 | 加固计划阶段一目标;待启用规则 | +| 高危 2 | core MQ 未鉴权即 exec | `parse_data_from_mq` 对 list/kill/exec 未鉴权即经 `/bin/sh -c` 执行;core 以 root 运行 → 本地 root RCE | 加固计划阶段二核心项 | +| 高危 3 | 内部服务零信任缺失 | pymsg 无认证;db 的 `execute` 路由接受任意 action/table/where,仅依赖 127.0.0.1 隔离 → 边界失守后可免认证读写全库 | 加固计划阶段三(AES-GCM) | +| 中危 1 | ai_review 未鉴权 + 提示注入 | `/review` 仅 per-IP 限流、无鉴权;用户输入直接拼入系统提示词 → 审核绕过 + 开放 LLM 端点 | aibox_open_dev_plan 跟踪 | +| 中危 2 | 密钥配置缺陷 | `.env.example` 写 `OPENAI_API_KEY` 而代码读 `DEEPSEEK_API_KEY` → 变量名不一致的静默失效 bug | 待对齐 | + +### 5.3 安全加固计划(三层防线) + +`docs/security/SECURITY_HARDENING_PLAN_20260803.md` 定义了"隔离层 + 认证层 + 加密层"三阶段目标: + +- **阶段一(隔离加固,P0)**:所有内部服务绑 127.0.0.1(✅ 已实现 db/confs/captcha/gateway/static/smtp/dnfs);防火墙仅放行 443、外网端口扫描验证仍 `[ ]` 待办。 +- **阶段二(core 密钥注入,P1)**:core 启动时生成进程组密钥,经 `execve` 的 envp 注入 `MICROSERV_KEY`,子进程 fail-fast 读取——仍 `[ ]` 待办。 +- **阶段三(AES-GCM 通信加密,P1)**:编写 `microcrypt` 库,接入 pymsg 帧与 HTTP 调用,防篡改/重放——仍 `[ ]` 待办。 + +### 5.4 安全审计覆盖(`docs/security/`,41+ 篇) + +包含全局审计(DEPLOY / DEPS / SECURITY_HARDENING_PLAN)与逐模块审计报告(waf、gateway×3、core、db、db2、pymsg、dnfs、dnfs2、static/fsys、ai_review、smtp、smtp3、captcha、captcha2、confs、libmsg、libhttp、libsqlite3、libth、aibox、BotOps、actpred)。`docs/reviews/` 另有 4 篇代码审查日志。可审计性远超多数同类项目,是风险闭环的基底。 + +--- + +## 6. 部署与运维 + +### 6.1 依赖 + +- **系统级**:`g++`(C++20)、`make`、`libboost-all-dev`、`libcurl4-gnutls-dev`、`libssl-dev`、`libsqlite3-dev`、`python3` + venv + pip、`patchelf`、`golang-go`(Go 1.22+,用于 waf)、`-ljpeg -lpng`(lci)。 +- **Python**:Flask、Flask-CORS、Flask-SQLAlchemy、SQLAlchemy、waitress、openai、chromadb、python-dotenv、nuitka。 +- **Go**:corazawaf/coraza v3.3.0、gopkg.in/yaml.v3。 + +### 6.2 安装链(一键脚本) + +```bash +# 1. 系统依赖 +bash _setup.deb.sh # Debian/Ubuntu +# 或 +bash _setup.rhel.sh # RHEL/CentOS/Rocky/Fedora + +# 2. 依次构建安装(库先行,core 最后) +bash _inst.sh +``` + +单独安装某服务:`bash _set.sh`(构建+安装)、`bash _run.sh`(运行)。部署路径约定 `/opt/micro_servers/`。 + +### 6.3 运行 + +`init.txt` 自启动顺序重要(redirect80 → waf → gateway → …)。启动 core: + +```bash +systemctl start Nidus # 或 bash core/_run.sh +``` + +对外入口:`https://:443`(waf 终止 TLS 后转发)。 + +### 6.4 WAF 与 gateway 协作 + +启用 WAF 后证书从 gateway 迁到 waf:`cp gateway/full_chain.crt gateway/server.key waf/certs/`。gateway 改内部 HTTP 模式(`tls=off`、`address=127.0.0.1`、`port=8443`→现 8445)。独立部署(不用 WAF)时 gateway 自行 `tls=on`、`port=443`、`address=0.0.0.0`。 + +### 6.5 容器化现状 + +`docker-compose.yml` 的 services 块**仅纳入 db / ai_review / dnfs 三个服务**(另含 networks 与 volumes),core/waf/gateway/fsys/confs/captcha/smtp 未纳入 → 编排不完整。生产部署当前以 systemd 链路为准。 + +--- + +## 7. 测试与质量 + +- **黑盒测试**:`tests/blackbox/` 约 8 个集成测试,覆盖 db / dnfs / gateway / waf / static / captcha / smtp / ai_review;无单元测试、无 CI(仓库无 `.github/workflows`)。 +- **文档/审计完备度**:`docs/security/` 24+ 份逐模块审计 + `docs/reviews/` 评审日志,可审计性极高。 +- **双实现(v1/v2)重构负担**:db↔db2、dnfs↔dnfs2、pymsg↔libmsg、libtry↔libth、lci↔bot4cj 并存,正以「C++ 重写 Python 微服务」为目标迁移。任一逻辑修正需两语言同步,存在语义漂移风险——建议重构收口时优先合并单轨。 + +--- + +## 8. 开发路线图与近期重点(2026-08) + +### 8.1 C++ 重写潮(2026-08-09 引入) + +| 新增/重写模块 | 说明 | +|--------------|------| +| **ca** | 中央认证服务(C++ 2463 行),认证独立化,接管原 gateway 端口前置鉴权 | +| **captcha2** | C++ 重写 captcha(含 stb_image_write),修复 P0 大小写缺陷 | +| **confs2** | C++ 重写 confs(libmsg RpcServer 替代 pymsg),协议兼容零改动 | +| **smtp3** | C++ 重写 smtp(1013 行,SMTP_SSL 手写),审计 7 项遗留一并修复 | +| **core ConfsTask** | C++ 内嵌配置任务(557 行) | +| **gateway 精简** | `src/main.cpp` 大幅精简(-1980 行),认证逻辑下沉至 ca | + +### 8.2 认证独立化(auth_service_plan) + +`waf → ca → gateway` 前置拓扑:ca 统一鉴权并前置转发,gateway 退化为纯转发(仅 loopback),下游 / WAF / 前端零改动。对应开发文档见 `docs/reports/auth_service_plan.md`。 + +### 8.3 关键 dev docs 索引(`docs/reports/`) + +core_service_registry_dev_doc(注册中心)、auth_service_plan(CA 模块)、aibox_open_dev_plan / aibox_file_network_cli_refactor(aibox 安全沙箱与 CLI 化)、libcrypt_CBC_deprecation_dev_doc(AES-GCM 迁移)、libhttp_remote_addr_dev_doc(X-Remote-Addr 透传)、captcha_cpp_rewrite / smtp_cpp_rewrite / confs2_cpp_rewrite(C++ 重写方案)、actpred_pretrain_test(预训练与推理测试)。 + +### 8.4 安全评级演进 + +Gateway v0.8.0 修复 P0 后,**安全评级 B+ → A-**;随 ca 引入与 C++ 重写潮加固,整体向"端到端一致鉴权"收敛(详见第 5 章待办)。 + +--- + +## 9. 许可证与推广 + +- **许可证**:各模块 MIT。 +- **价值主张摘要**(详见 `docs/blackbird_promo_pack.md`): + - "微服务的好处,Kubernetes 的麻烦,二选一?Blackbird 说:都要,但只留好处。" + - "你的数据、你的服务、你的规则——一台机器,全部自己说了算。" + - Slogan 候选:*轻装微服务,主权握手中*;*一台服务器,一座可控的城*;*微服务的纯粹主义*。 + +--- + +## 10. 风险与待办(收口) + +| 风险 / 待办 | 级别 | 状态 | 来源 | +|------------|------|------|------| +| WAF 检测规则未启用 | 高危 | `human_review_pending`(计划阶段一目标) | 研究报告 / 加固计划 | +| core MQ 未鉴权 RCE(root 运行) | 高危 | `human_review_pending`(计划阶段二) | 研究报告 / 加固计划 | +| 内部 pymsg/db 零信任缺失 | 高危 | `human_review_pending`(计划阶段三) | 研究报告 / 加固计划 | +| ai_review 未鉴权 + 提示注入 | 中危 | `human_review_pending` | 研究报告 / aibox_open_dev_plan | +| 密钥变量名不一致(DEEPSEEK/OPENAI) | 中危 | `advisory`(待对齐) | 研究报告 | +| docker-compose 仅 3 服务,不完整 | P2 | `advisory` | 研究报告 | +| 无单元测试 / 无 CI | P2 | `advisory` | 研究报告 | +| v1/v2 双实现维护成本 | 结构性 | `advisory`(建议收口合并) | 研究报告 | +| 文档口径差异(MODULES 记 gateway:8443) | 低 | `advisory`(以 README 为准) | 本文档核实 | + +### 建议交付清单 + +- [ ] 启用 WAF 规则并补建 `crs/`(直击高危 1) +- [ ] 为 core MQ 通道落地 `verify_admin_token` 并降权运行(直击高危 2) +- [ ] 内部服务加调用方鉴权 / pymsg 上 mTLS 或 Unix socket(直击高危 3) +- [ ] ai_review `/review` 加鉴权 + 结构化提示词拼接 +- [ ] 统一 `DEEPSEEK_API_KEY` 与 `.env.example` +- [ ] 补全 compose 或文档声明 systemd 为唯一受支持链路 +- [ ] 引入单元测试与 CI,降低双实现回归风险 + +--- + +## 续接胶囊 + +- **文档类型**:项目综合资料长文档(Blackbird / micro_servers) +- **目标读者**:开发者、维护者、安全审计者、潜在贡献者 +- **核心目标**:将分散在 40+ 篇仓库文档中的架构、模块、协议、安全、部署、路线图整合为单一可查阅手册 +- **已完成章节**:第 0–10 章(概述、架构、模块清单、pymsg 协议、安全体系、部署运维、测试质量、路线图、许可证、风险收口) +- **已确认事实**:主 README 拓扑(waf:443→ca:8443→gateway:8445);ca 为 C++ 认证前置模块;C++ 重写潮(ca/captcha2/confs2/smtp3/gateway 精简/core ConfsTask);安全评级 B+→A-;MIT 许可 +- **待核验事项**:3 项高危 + 2 项中危是否已在最新提交修复(研究报基于 2026-08-08 快照);docker-compose 补全状态;MODULES.md 端口口径同步 +- **下一节唯一目标**:(可选)补充"各模块 API 速查表"或"从零部署实战 walkthrough" +- **续写口令**:`继续编辑 docs/blackbird_project_profile.md,当前停于第 10 章风险收口;已含架构/模块/协议/安全/部署/路线图;约束:以主 README 拓扑为准、高危缺口标注 human_review_pending、不虚构修复状态;下一目标:补模块 API 速查表或部署实战。` diff --git a/docs/reports/fsys_public_frontend_research_20260810.md b/docs/reports/fsys_public_frontend_research_20260810.md new file mode 100644 index 0000000..a86c6fe --- /dev/null +++ b/docs/reports/fsys_public_frontend_research_20260810.md @@ -0,0 +1,141 @@ +# fsys/public 前端代码研究报告 + +> 日期:2026-08-10 · 范围:`fsys/public/` 全部前端代码(**不含 `games/` 目录**) · 托管方:fsys(C++20,127.0.0.1:9200) + +--- + +## 一、总览 + +fsys/public 是 UniServe 框架对外的全部 Web 前端,由 fsys 静态托管,经 `waf:443 → ca:8443 → gateway:8445 → fsys:9200` 链路送达浏览器。整套前端为**零构建、零框架的原生 HTML/CSS/JS**(Vanilla 技术栈),无打包器、无 npm 依赖,第三方库仅两个 vendored 文件(markdown-it 12.0.0、highlight.js 11.9.0)。 + +### 代码规模(不含 games/) + +| 类别 | 文件 | 行数 | 说明 | +|------|------|------|------| +| 自研 JS | 8 个 | ~2,650 | 业务逻辑主体 | +| 第三方 JS | 2 个 | ~9,500 | markdown-it / highlight.js(vendored,不分析) | +| CSS | 8 个 | ~2,370 | 含设计令牌体系 theme.css | +| HTML | 13 个 | ~2,100 | 含 allcolor.html 内联数据 ~400 行 | +| 合计(自研) | 26 个 | **~7,100** | | + +### 页面地图 + +``` +public/ +├── index.html 社区首页( landing,Hero + 特性 + 关于 + CTA ) +├── login.html 登录(图形验证码 + 用户条例弹窗 + 第三方 yhdet 快捷登录) +├── register.html 注册(图形验证码 + 邮箱验证码双因子) +├── forgot.html 重置密码(同注册双因子流程,脚本内联) +├── dnfs.html 树状笔记主应用(核心 SPA 式单页) +├── aibox.html aibox 智能体 Web 客户端(WebSocket,仅管理员) +├── __view.html 目录浏览页(fsys 无 index.html 时的回退页,__ 前缀被 filelist 过滤) +├── allcolor.html 中国传统色彩调色板(纯静态工具页,内联数据) +├── LICENSE.html 用户使用条例(静态文本,供登录页 iframe 弹窗复用) +├── mgmt/ 进程管理器(管理员后台,iframe 嵌套 features/*.html) +│ ├── index.html 旧版独立登录页(疑似遗留,见 §六问题 P1) +│ ├── mgmt.html 管理主框架(左侧功能列表 + iframe 加载功能页) +│ └── features/ process(可用) / user / module / log(占位) +├── css/ theme / index / auth / dnfs / view / aibox / codeblock(空) +└── js/ token_manager / validation / index / login / register / dnfs / aibox / view +``` + +--- + +## 二、认证体系:HttpOnly Cookie + Token 生命周期管理 + +整套前端已在 2026-08 完成向 **HttpOnly Cookie(q4_token)** 的迁移,JS 全程不经手 Token,这是本次研究中最重要的一条架构主线。 + +### 2.1 token_manager.js(119 行,全局基础设施) + +被 index / dnfs / aibox 三页引用,做两件事: + +1. **定时静默刷新**:通过 `POST /whoami` 取 `created_at + keep_time` 估算过期点(注释明确指出不能用 `iat`——刷新后 iat 不变),在 80% 生命周期处调 `POST /refresh_token`;失败进入 15s 冷却重估,两次刷新最小间隔 60s。 +2. **全局 fetch 拦截器**:覆写 `window.fetch`,任何请求收到 401 先自动刷新一次 Token 再重试原请求;`/refresh_token` 自身排除防循环。Cookie 由 gateway `Set-Cookie` 自动更新,重试无需改请求头。 + +### 2.2 各页登录态处理 + +| 页面 | 检测方式 | 401 处理 | +|------|----------|----------| +| index | `POST /whoami`,已登录则切换头部按钮组与 CTA 文案 | 静默忽略(首页允许匿名) | +| dnfs | `loadUserPanel()` 拉 `/whoami`,按 `is_admin` 显示特殊节点面板与管理入口 | 仅笔记接口 401 跳 login.html,其他错误原地提示(不再误判凭证失效) | +| aibox | 启动预检 `/whoami`,非管理员仅提示不阻塞 | WS 握手由 gateway 强制 is_admin 兜底 | +| mgmt | `mgmt.html` 内联 `loadUserInfo()`,未登录 1s 后跳 `index.html` | features/process.html 遇 401 弹窗后跳登录 | + +### 2.3 注册/登录/重置三流程 + +- **login**:邮箱 + 密码 + 图形验证码(`GET /captcha/image`,token 走 `X-Captcha-Token` 响应头,图片 blob → ObjectURL,旧 URL 主动 revoke)。无论成败提交后强制刷新验证码(token 一次性消费)。另有 yhdet 开源社区第三方快捷登录入口(外跳 callback)。 +- **register**:图形验证码 → `POST /register/send_code` 发 6 位邮箱验证码(10 分钟有效,前端 60s 重发倒计时与服务端冷却对齐,HTTP 429 时也启动倒计时)→ `POST /register` 提交。 +- **forgot**:与 register 几乎同构,走 `/reset/send_code` + `/reset_password`;脚本**直接内联在 HTML 里**(339 行中约 290 行是 register.js 的复制改造)。 +- **WafTip**(validation.js):统一识别 WAF 拦截特征(403 + 纯文本 `blocked by WAF`),与 gateway 自身的 JSON 格式 403 区分,三处表单均接入。 + +--- + +## 三、dnfs 树状笔记(dnfs.html + dnfs.js 1187 行,核心应用) + +### 3.1 导航模型 + +- 用 `stack` 数组记录节点路径(节点 id 栈,根为 0),点卡片标题 push、返回 pop,配合 `getNode(id)` 拉子节点列表。 +- `Target-Url: http://127.0.0.1:8006` 请求头由 gateway 转发到 dnfs2。 +- **导航守卫** `confirmLeaveIfDirty()`:表单有未提交内容时拦截导航(明确注释强调必须在改 stack 之前调用,否则栈错位)。 +- 右悬浮 **minimap**(当前层节点锚点跳转 + 折叠),左悬浮 **userpanel**(用户名/角色/特效开关/管理入口/退出),窄屏(<768px)默认折叠。 + +### 3.2 内容渲染管线 + +- 普通节点:markdown-it(`html: false`)+ highlight.js 代码高亮。 +- **特殊节点**(管理员专属,信封格式 `{"_sp":"link|js|image|file", ...}`): + - `link`:favicon 经服务端代理 `/api/favicon?url=`(SSRF 防护在 fsys 侧),新标签 `noopener noreferrer`。 + - `js`:可审计/可运行的前端特效,**iframe `sandbox="allow-scripts"` + srcdoc** 隔离执行,不用 eval/new Function(CSP 未开 unsafe-eval);`` 标记决定挂在卡片内还是 fixed 全屏(注释详细论证了层叠上下文陷阱);用户面板提供"无特效模式"开关(localStorage 持久化)。 + - `image`:DataURL 直显;`file`:base64 → Blob 触发下载;上传上限 2.5MB(与后端 3.5M base64 字符上限对齐)。 +- 权限显隐:发布权限后端强制(is_admin),前端仅按 `can_operate` 字段渲染编辑/移动/删除按钮组。 + +### 3.3 其他特性 + +- 当前层实时搜索(标题/owner/内容,信封类排除 base64),ESC 清空,无匹配有提示。 +- 节点移动 = pid 变更的 update_note,底部 movebar 二次确认;移动/发布会走后端 AI 审核,期间按钮组禁用防重。 +- 互动统计图标(观看/点赞/分享)已就位,但后端 Notes 表无计数字段,恒显示 0(预留)。 +- 大量防御性注释记录了历史 bug 修复(空栈取 `stack[-1]` 得 undefined、confirm 取消时 Promise 兜底恢复按钮等)。 + +--- + +## 四、aibox Web 客户端(aibox.html + aibox.js 435 行) + +- **WebSocket** 经 gateway `[WsProxy]` 反代至 aibox 服务(`/ws/aibox`),协议与 BotOps/aibox `client.py` 完全兼容。 +- 完整流式渲染:chunk 增量拼接 + markdown-it 渲染;reasoning 思考区可折叠、结束后默认折叠、超长仅保留末尾 3000 字符;`ai_break` 支持工具调用分段气泡;中断(interrupt)有完整状态收尾。 +- 连接韧性:指数退避重连(2s→30s 封顶)、10s 心跳(低于前置代理 proxy_read_timeout)、手动断开抑制重连。 +- 任务面板为抽屉式覆盖层,未读角标(99+ 封顶);本地命令 `/clear /help /connect /disconnect /interrupt`,其余 `/` 命令透传服务端。 +- 移动端细节:`enterkeyhint="send"`、`isComposing` 防中文输入法误发、viewport-fit=cover 刘海屏适配。 + +## 五、__view 目录浏览(__view.html + view.js) + +fsys 对无 index.html 目录的回退浏览页(`__` 前缀使其被 `/api/filelist` 过滤,不出现在列表里)。面包屑 + 搜索(`/` 或 Ctrl+F 聚焦、200ms 防抖、ESC 清空)+ 分类统计(目录/文件/视频/音频)+ 网格列表;视频音频跳 `/video/`(fsys Range 206 流式),`?download=true` 触发下载。所有文件名经 `esc()` 转义防 XSS。 + +## 六、mgmt 进程管理器(管理员后台) + +- `mgmt.html`:顶栏用户信息 + 左侧功能列表 + iframe 加载功能页;功能列表中日志页已被注释停用。 +- `features/process.html`:**唯一真正可用的功能页**,经 gateway 代理 core:5200,实现进程列表(兼容 boost property_tree 把数组序列化成对象的怪癖)、新建(/exec)、停止(/kill)、401 跳登录。 +- `features/user.html` / `module.html` / `log.html`:占位静态页,按钮仅 alert"需要后端 API 支持"。 + +## 七、CSS 设计体系 + +- **theme.css(686 行)是全站基座**:完整 Design Tokens(`--bg/--fg/--accent/--error...` 约 24 个变量),`prefers-color-scheme` 暗色全套覆写,暖棕橙品牌色(accent `#e8853a`),统一表单/按钮/提示(tip-red/yellow/green)/卡片/页脚,480px/360px 两档响应式。 +- 页面级 CSS 在其上叠加:index.css(landing 各 section + 滚动渐显 + 光标光斑)、auth.css(注册/重置页品牌渐变顶条)、dnfs.css(点阵底纹、卡片逐张入场动画、`prefers-reduced-motion` 降级)、view.css / aibox.css(全屏应用布局覆盖 theme 居中卡片默认)。 +- 一致性良好:动效全部尊重 `prefers-reduced-motion`,悬浮面板统一 backdrop-filter 毛玻璃,暗黑模式覆盖完整。 + +## 八、发现的问题与改进建议 + +| # | 级别 | 位置 | 问题 | +|---|------|------|------| +| P1 | 中 | mgmt/index.html + mgmt.html | **旧认证体系遗留**:自建 `/api/login` + JS 写 `token=` Cookie(非 HttpOnly q4_token),logout 删的也是 `token` Cookie,与现行认证完全脱节;该登录页应删除或改造,避免成为绕过口 | +| P2 | 中 | js/view.js | 文件名经 `esc()` HTML 转义后仍**拼进 `onclick="navigate('${path}')"` 内联字符串**:`'` 在属性解析时会解码回单引号,单引号文件名可断开 JS 字符串造成注入。建议改 addEventListener + dataset | +| P3 | 低 | register.js / forgot.html | `POST /register`、`/reset_password` 声明 `Content-Type: application/x-www-form-urlencoded` 但 body 实为 JSON 字符串(后端兼容故能用,契约不洁) | +| P4 | 低 | login.js / register.js / forgot.html | refreshCaptcha / startResendCooldown / 校验三件套**复制了三份**,forgot 干脆内联 290 行;建议抽 `js/auth_common.js` | +| P5 | 低 | js/dnfs.js | 非严格模式下 `obj/jsonBody` 等多处未声明即赋值(隐式全局);`card.id = item.title` 标题重复或含特殊字符时锚点冲突 | +| P6 | 低 | 空文件 | `css/codeblock.css`(0 行,dnfs.html 仍引用)、`mgmt/features/log.css`(0 行) | +| P7 | 低 | mgmt/features/{user,module,log}.html | 占位页无实现,入口仍展示"模块/用户"按钮,建议隐藏或标注 | +| P8 | 提示 | dnfs.js 统计图标 | visit/like/share 前端已渲染但后端无字段,恒为 0 | + +## 九、结论 + +fsys/public 前端在零框架约束下达到了相当高的完成度:**认证设计现代化**(HttpOnly Cookie + 静默刷新 + 401 拦截重试)、**安全细节扎实**(WAF 特征识别、验证码一次性消费、iframe 沙箱特效、SSRF 防护代理、favicon blob 回收)、**可访问性与移动端适配到位**(reduced-motion、enterkeyhint、isComposing、safe-area)。注释质量突出,大量历史 bug 的成因与防御约定都沉淀在代码里。 + +主要欠账集中在 **mgmt 子系统**(旧认证遗留 + 三个占位页)和**三处表单脚本的复制粘贴**。优先级建议:P1(旧登录页拆除)> P2(view.js 内联事件注入)> P4(公共脚本抽取)> 其余。