From 9dbe395484a218672cd82cf3555ee962d481cb34 Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Mon, 3 Aug 2026 13:13:52 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E5=86=85=E7=BD=91?= =?UTF-8?q?=E9=80=9A=E4=BF=A1=E5=AE=89=E5=85=A8=E5=8A=A0=E5=9B=BA=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/SECURITY_HARDENING_PLAN.md | 152 ++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 docs/SECURITY_HARDENING_PLAN.md diff --git a/docs/SECURITY_HARDENING_PLAN.md b/docs/SECURITY_HARDENING_PLAN.md new file mode 100644 index 0000000..3d5af8d --- /dev/null +++ b/docs/SECURITY_HARDENING_PLAN.md @@ -0,0 +1,152 @@ +# micro_servers 内网通信安全加固 · 开发计划 + +> 项目:qing/micro_servers(DIY 轻量微服务框架) +> 场景:单机部署(所有服务同一台,仅 waf:443 对外) +> 目标:在"单机 + 绑 127.0.0.1"基础上,补齐服务间认证与加密 +> 状态:计划 v1.0 + +--- + +## 0. 决策摘要(来自需求讨论) + +| 问题 | 结论 | +|------|------| +| 内网是否需要独立鉴权 | 网络隔离为主(绑127.0.0.1),高危面另加服务间认证 | +| 能否用用户密钥做认证 | 对外链路可用;服务间互调改用独立 service key | +| 能否用 RSA+AES 通信加密 | 能,但单机场景 RS‌A 公钥分发太麻烦,不划算 | +| 最终方案 | **core 生成进程组密钥 → 环境变量注入 → AES-GCM 服务间加密** | +| 分发方式 | 由 core 作为密钥生成/分发中心,免手动拷贝 | + +--- + +## 1. 总体目标 + +为 micro_servers 的内网服务间通信建立**三层防线**: + +1. **隔离层**(地基):所有内部服务绑定 `127.0.0.1`,云安全组仅放行 443 +2. **认证层**:服务间调用携带共享密钥(进程组密钥)校验身份 +3. **加密层**:敏感通信用 AES-256-GCM 加解密 + 完整性 + 防重放 + +--- + +## 2. 架构变更(目标态) + +``` + 外网攻击者 ──只能到达──► 只开放 waf:443 + │ + ┌────────────────────────┴───────────┐ + │ core (:5200, 本机) │ + │ [密钥生成器] 生成进程组密钥 │ + │ 通过环境变量 MICROSERV_KEY 注入 │ + └─────┬──────────────────────────────┘ + │ 拉起 + 注入密钥 + ┌────────┬────────┬───┴───┬────────┬────────┬─────────┐ + ▼ ▼ ▼ ▼ ▼ ▼ + waf gateway static dnfs db ai_review ... + :443 :8443 :9200 :8006 :8005 :8007 + 全部绑定 127.0.0.1(仅本机可达) + 服务间调用:AES-GCM 加密 + 进程组密钥认证 +``` + +--- + +## 3. 工作分解(3 阶段) + +### 阶段一:隔离加固(P0,先行) +对齐"绑 127.0.0.1 + 只放行 443"的基线。 + +- [ ] 1.1 检查并修改所有服务监听地址为 `127.0.0.1`(禁止 `0.0.0.0`) + - waf 例外:443 对外;但可考虑 waf 内部转发目标为 127.0.0.1:8443 +- [ ] 1.2 云安全组 / ufw:仅放行 TCP 443,其余端口公网关闭 + - 规则示例:`ufw default deny incoming` + `ufw allow 443/tcp` +- [ ] 1.3 验证:从外网 curl 各内部端口(8443/9200/8005…)应全部超时/拒绝 +- [ ] 1.4 验证:本机 `curl http://127.0.0.1:8443` 正常(确认仅本机可达) + +**完成标准**:对外仅 443 一个口,内部端口公网不可达。 + +--- + +### 阶段二:core 密钥生成 + 环境变量注入(P1 核心) +实现"core 作为进程组密钥中心"。 + +- [ ] 2.1 core 启动时生成随机密钥 + - 实现:`openssl rand -hex 32`(或 C++ 读取 /dev/urandom 256 位) + - 输出:32 字节(256 位)十六进制串作为进程组密钥 +- [ ] 2.2 core 拉起子进程时注入环境变量 + - 用 `execve` 的 envp 直接传 `MICROSERV_KEY=`(勿用全局 export,减少暴露) + - 涉及子进程:ai_review/db/dnfs/smtp/static/waf/gateway/captcha/aibox +- [ ] 2.3 子进程侧读取密钥 + - 各服务启动时读 `os.environ["MICROSERV_KEY"]` + - **fail-fast**:读不到立即报错退出,禁止静默降级为明文 +- [ ] 2.4 core 接口安全复核 + - core(:5200) 必须:只绑 127.0.0.1 + 管理接口带鉴权 + - 说明:core 现为"主钥匙",是最高价值目标,重点保护 + +**完成标准**:所有由 core 拉起的服务均带 `MICROSERV_KEY`,缺失时报错退出。 + +--- + +### 阶段三:服务间 AES-GCM 加密通信(P1) +用预共享的进程组密钥加密服务间流量。 + +- [ ] 3.1 编写统一加解密库 `microcrypt` + - 目标语言:Python(pymsg/Flask 服务)+ C++(gateway)各一份,接口对齐 + - 算法:AES-256-GCM + - 加密:随机 12 字节 nonce + 明文 → (nonce, ciphertext, tag) + - 解密:nonce + tag 校验,失败即拒绝 + - 防重放:帧内携带时间戳/序号,接收方校验新鲜度 +- [ ] 3.2 接入 pymsg 帧(db/captcha/smtp/confs 等基于 pymsg 的服务) + - 在长度前缀帧的 payload 外包一层 GCM 加密 +- [ ] 3.3 接入 HTTP 服务(static/dnfs/ai_review/gateway 的互相调用) + - 敏感请求体加密,或至少加认证 header + 加密关键字段 +- [ ] 3.4 密钥轮换 + - core 重启即换新密钥(进程生命周期天然轮换) + - 配置项:可设定期轮换(可选,P2) +- [ ] 3.5 回归测试 + - 正常链路:注册/登录/笔记 CRUD/日志上报 全流程可跑通 + - 故障测试:错误密钥/乱序/篡改 → 服务应拒绝而非崩溃 + +**完成标准**:服务间敏感通信已 GCM 加密,篡改/伪造被拒。 + +--- + +## 4. 风险与对策 + +| 风险 | 对策 | +|------|------| +| 环境变量对同机进程可见(/proc//environ) | 接受局限:威胁模型以"防外网"为主;不把 key 当终极秘密;仅绑本机+少暴露 | +| core 被攻破 → 主钥匙泄露 | 将 core 作为最高价值目标:绑本机、接口精简、强鉴权、最小权限 | +| 调试时手动跑单服务导致 key 缺失/不一致 | fail-fast 报错 + 统一由 core 拉起,文档明确"禁止手动裸跑" | +| AES-GCM 误用(nonce 重用等) | 库内统一封装,nonce 每次随机生成;禁止外部传入 | +| 明文降级残留 | fail-fast + 代码审查禁止"No key → 明文"分支 | + +--- + +## 5. 里程碑 + +| 里程碑 | 内容 | 预估 | +|--------|------|------| +| M1 | 阶段一:隔离加固完成,对外仅 443 | 0.5 天 | +| M2 | 阶段二:core 密钥注入 + 子进程读取 | 1 天 | +| M3 | 阶段三:AES-GCM 库 + 接入全部服务 | 2-3 天 | +| M4 | 回归测试 + 安全验证(篡改/伪造/重放) | 1 天 | + +--- + +## 6. 验证清单(上线前) + +- [ ] 外网端口扫描:仅 443 开放 +- [ ] 内部端口仅 127.0.0.1 可达 +- [ ] 所有 core 拉起服务均带 MICROSERV_KEY +- [ ] 缺失密钥 → 服务 fail-fast 报错(无明文降级) +- [ ] 错误/篡改密文 → 服务拒绝请求 +- [ ] 完整业务链路回归通过 +- [ ] MICROSERV_KEY 未提交进 git(.env/.gitignore) + +--- + +## 7. 备注 / 后续可选项(P2) + +- 密钥定期轮换定时器 +- mTLS 升级路径(若未来改多机部署) +- 审计日志:记录服务间认证失败/解密失败事件