MongoDB 安全加固(授权、TLS、角色、审计)
MongoDB难度: 高级耗时: 10 分钟(审计)– 2 小时(完整加固)按场景组织的 runbook,用于在不停机的情况下加固正在运行的 MongoDB(单服务器、replica set 或 sharded cluster):只读安全审计、通过 keyFile + transitionToAuth 以 rolling 方式启用授权、最小权限的 custom role 和用户、SCRAM-SHA-256、bindIp 与防火墙、allowTLS → preferTLS → requireTLS 迁移、x.509 成员认证、审计日志(Enterprise/Percona)以及 encryption at rest;最后重新运行审计,证明风险已消除。用本站安装指南部署的系统已启用授权和 keyfile:先运行审计,只执行结果为“风险”的场景。日常运维和备份见其他 MongoDB 指南。
架构: 单服务器、3 个及以上成员的 replica set 或 sharded cluster
场景
- 安全状态审计(只读) — 不做任何修改。将匿名访问、监听地址、TLS、认证机制、高权限用户、审计和 encryption at rest 的状态报告为 OK / 警告 / 风险。如果不知道从哪里开始,请选择此项。
- 完整加固(按顺序全部执行) — 审计 → 内部认证 + 授权(通过 transitionToAuth 不停机)→ 最小权限用户 → SCRAM-SHA-256 → bindIp/防火墙 → TLS(allowTLS → preferTLS → requireTLS)→ 审计日志(Enterprise/Percona)→ 最终审计。在 replica set 中以 rolling 方式进行;每个有风险的步骤都需要确认。
- 授权已关闭:启用 authorization(keyFile,不停机) — 任何人无需用户名/密码即可连接。在 replica set 和 sharded cluster 中通过 keyFile + transitionToAuth 以 rolling 方式不停机启用;单服务器需要一次短暂重启。
- 最小权限用户和 custom role(应用、备份、监控) — 应用使用 root 或共享的管理员账号连接。为应用创建只授予其自身数据库所需操作的 custom role,并为备份和监控创建单独的用户;同时说明如何在 cron/应用侧安全保存密码。
- 关闭 SCRAM-SHA-1,只用 SCRAM-SHA-256 — 旧用户的凭据以 SHA-1 保存,或审计发现 SCRAM-SHA-1 处于启用状态。将用户迁移到 SHA-256,然后通过 rolling 重启收紧 authenticationMechanisms。
- 收紧网络访问(bindIp 0.0.0.0、防火墙) — mongod 在所有接口上监听(0.0.0.0、bindIpAll),或端口对所有人开放。将 bindIp 缩小到 localhost + 服务器内网 IP,防火墙只允许成员和应用网络访问。Rolling 方式,不停机。
- 加密连接:TLS(allowTLS → preferTLS → requireTLS) — 应用与成员之间的流量未加密。分发证书后,先以 allowTLS 对成员进行 rolling 启用,然后在运行中切换到 preferTLS,应用准备就绪后再切换到 requireTLS。可选:成员间 x.509 认证。
- 启用审计日志(Enterprise / Percona) — 必须记录谁在何时登录、用户/角色变更以及 drop 操作。在 MongoDB Enterprise 和 Percona Server for MongoDB 中通过 auditLog 启用;Community 版没有此功能(给出替代方案)。
- Encryption at rest(加密磁盘上的数据) — 即使磁盘或备份被盗,数据也无法读取。在 Enterprise/Percona 中,通过逐个以 initial sync 重建成员来启用 WiredTiger 加密;在 Community 中用 LUKS 加密数据盘。
开始之前
- 所有 mongod… 和 mongos… 服务器上的 root/sudo 权限;从第一台服务器到其他服务器的 SSH(用于复制 keyfile 和证书)。
- …Replica set 健康:所有成员均为 PRIMARY/SECONDARY,延迟低。不健康的集群上不执行 rolling 操作。…mongod 正在运行。…
- 应用清单及其负责人:在授权/TLS 变为强制之前,需要更新每个应用的连接字符串。连接字符串必须包含所有成员和 replicaSet=(以免在 rolling 重启期间断开)。
- 维护窗口:rolling 操作不停机,但每次 primary 切换时写入会等待几秒。单服务器上启用授权/TLS 需要短暂停机。
- 如果 sharded cluster 中已启用授权:每个 shard 的 primary 上必须有一个与 mongos 上 … 同名同密码的 shard-local 用户(root)。按成员执行的步骤(rolling 重启中的 rs.stepDown、setParameter、审计)会直接连接 shard 成员;mongos 用户在那里无效。检查:在 shard 成员上执行 mongosh --port <shard port>,再执行 db.getSiblingDB("admin").auth("…", passwordPrompt())。
- 最新且已验证可恢复的完整备份。
- 审计和 encryption at rest 需要 MongoDB Enterprise 许可证或 Percona Server for MongoDB。Community 版没有这些功能。
- 每台服务器都能解析成员名称(DNS 或 /etc/hosts);启用 TLS 后使用这些名称连接。
指南阶段
- 准备:安全网和辅助工具 — 配置和状态备份 · 安装 PyYAML · 编写 YAML 编辑工具(dbatlas-yaml) · 编写 rolling 重启工具(dbatlas-mongod-restart) · 将管理员密码写入临时文件
- 状态审计(只读) — 网络、进程和文件权限:… · 网络和进程:… · 授权、TLS 和参数:… · 授权、TLS 和参数:… · 用户、角色和认证机制 · 将发现项对应到场景
- 授权:诊断和 keyfile — 诊断:授权真的已关闭吗? · 清点应用连接 · 创建 keyfile · 将 keyfile 复制到其他服务器 · keyfile 权限:… · keyfile 权限:…
- 授权:管理员用户 — 创建管理员用户(…) · Shard-local 管理员:…
- 最小权限用户和 custom role — 为应用创建 custom role(…@…) · 创建应用用户(…) · 备份和监控用户 · 验证最小权限(…) · 在应用和 cron 侧安全保存密码
- 授权:验证不再有未认证连接 — 未认证客户端连接:…
- 强制启用授权(单服务器) — authorization: enabled · 安全重启服务(…)
- 授权:验证 — 未认证访问是否被拒绝? · 验证最小权限(…) · 回退路径(如需要)
- SCRAM-SHA-256:迁移用户 — 拥有 SHA-1 凭据的用户 · 将用户缩减为只用 SCRAM-SHA-256
- SCRAM-SHA-256:验证 — SHA-1 登录是否被拒绝?
- 网络访问:防火墙 — 防火墙规则
- 网络访问:验证 — 监听地址:…
- TLS:证书 — 当前 TLS 状态 · 生成内部 CA 和服务器证书 · 分发证书 · 证书权限和校验:… · 证书权限:…
- TLS:迁移应用 — 将应用迁移到 TLS 并统计 TLS 连接
- TLS:验证 — 非 TLS 连接是否被拒绝:…
- 审计日志:预检查 — 该 mongod 是否支持审计:…
- 审计日志:验证和轮转 — 是否正在写入审计记录:… · Community 替代方案:监控认证日志
- Encryption at rest:预检查和备份 — 加密支持和磁盘空间:… · 是否已做完整备份?
- Encryption at rest:测试标记 — 写入明文标记
- Encryption at rest(Community):用 LUKS 加密数据盘 — 准备 LUKS 磁盘:… · 将数据迁移到加密磁盘:…
- 最终审计(加固后) — 网络、进程和文件权限:…(最终状态) · 网络和进程:…(最终状态) · 授权、TLS 和参数:…(最终状态) · 授权、TLS 和参数:…(最终状态) · 用户、角色和认证机制(最终状态)
- 清理和后续工作 — 删除临时密码文件 · 后续:监控和定期任务