跳转至

安全事故复盘报告 (Security Incident Post-Mortem)

[!DANGER] 事件定性:严重安全事故 (Critical Security Incident) 影响范围:服务器被非法控制(成为肉鸡/矿机),需销毁重建。

1. 事故根因分析 (Root Cause Analysis)

经过代码审计,确认之前版本的部署脚本存在严重设计缺陷

🚨 致命缺陷:Agent 端口全网暴露

  • 配置项Agent节点部署.md 中的 ops-portainer-agent 使用了 mode: host 且映射了 9001 端口。
  • 漏洞原理
    • Docker Swarm 的 ingresshost 模式如果不指定 IP,默认监听 0.0.0.0:9001
    • 在部署完成但尚未被主控端连接的间隙(Race Condition),该端口对全网开放且无身份验证。
    • 自动化攻击脚本(Botnet)扫描到该端口后,抢先连接 Agent,从而获得宿主机的 Root 权限。

⚠️ 次要缺陷:管理面板暴露

  • Traefik:曾开启 --api.insecure=true (端口 8080),泄露后端拓扑。
  • 数据库/Redis:部分文档未明确禁止映射数据库端口到公网。

2. 整改措施 (Corrective Actions)

已对所有部署文档进行重构,引入“零信任”机制。

领域 旧版方案 (Insecure) 新版方案 (Secure by Default)
防火墙 依赖 Oracle 默认安全组 OS级强制 (UFW/iptables),默认拒绝所有入站
Portainer 9000:9000 (公网暴露) 127.0.0.1:9000:9000 (仅本机) + SSH Tunnel
Agent 默认监听 0.0.0.0:9001 UFW 前置拦截 或 绑定内网 IP
Traefik Insecure Dashboard 强制 Auth 中间件 + 域名访问
权限 滥用 privileged: true 仅使用必要的 cap_add: NET_ADMIN

3. 预防机制 (Preventive Measures)

为了防止此类低级错误再次发生,已在 IDE 配置 (.gemini/GEMINI.md) 中植入 Production Mode 系统指令。

今后所有自动生成的代码将遵循: 1. Implicit Deny: 没有显式允许的端口一律不通。 2. Localhost First: 管理界面一律不直接暴露公网。 3. Audit: 任何 privileged/var/run/docker.sock 的使用都会被严格审查。

给用户的建议: 无论我们在文档中写得多么完美,公网环境始终充满了恶意扫描。 请务必养成“先关防火墙,再开服务”的肌肉记忆。