Files
micro_servers/docs/security/SECURITY_HARDENING_PLAN_20260803.md
qing d3158c2420 docs: add date suffix to remaining documentation files
- Rename SECURITY_HARDENING_PLAN.md -> SECURITY_HARDENING_PLAN_20260803.md
- Rename aibox_SECURITY_AUDIT.md -> aibox_SECURITY_AUDIT_full_20260801.md
- Update INDEX.md links accordingly
2026-08-03 13:26:38 +08:00

153 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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=<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/<pid>/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 升级路径(若未来改多机部署)
- 审计日志:记录服务间认证失败/解密失败事件