本节摘要:传输层用 TLS 防窃听,静态层用磁盘加密或字段级加密防拖库后读明文,审计日志记录"谁在何时动了什么"。本节讲三道防线的落地配置与取舍。
某团队数据库本身做了网络隔离,但每天把未加密的备份归档传到一台老旧的文件服务器。攻击者拿到文件服务器权限,直接读走备份里的明文 BSON——等于绕过所有前端防线把库端走了。教训:加密要覆盖静态数据全链路,包括备份。
net: port: 27017 tls: mode: requireTLS certificateKeyFile: /etc/ssl/mongo.pem CAFile: /etc/ssl/ca.pem
复制集与分片集群的节点间通信同样要走 TLS,只加密应用到 mongos 的一段等于关了前门开后门。证书过期是高频事故:把证书有效期纳入监控(第 10 章),提前 30 天告警。
| 层次 | 手段 | 防什么 |
|---|---|---|
| 磁盘级 | 云盘加密 / LUKS | 物理盘失窃 |
| 引擎级 | WiredTiger 加密(企业版) | 文件被拷走 |
| 字段级 | 应用侧加密敏感字段 | 连 DBA 都不该看明文 |
字段级加密的思路是密钥永远不进数据库:身份证、手机号在应用层加密后再写入,数据库里只有密文,拖库者拿到的是一堆无法解读的字节。
// 应用侧字段加密示意(密钥在 KMS,不在库) db.users.insertOne({ uid: "u42", phone: encrypt("+8613800000000", keyRef), // 密文存储 phoneTail: "0000" // 冗余明文尾号供展示 });
auditLog: destination: file format: JSON path: /var/log/mongodb/audit.json filter: '{ atype: { $in: ["authenticate","createCollection","dropCollection","dropDatabase"] } }'
审计记录认证、DDL、删除等敏感事件。全量审计体积可观,用 filter 只记高危动作是常规折中。

💡 安全基线自查一句话:27017 只在内网可达、认证开启、应用非 root、节点间 TLS、备份加密、审计留痕——六项全过再谈上线。
文件服务器那次拖库的定位过程值得记录。数据库侧先是出现零星异常登录告警,安全团队封 IP、改密码、全员排查了一周没有结论——因为攻击者根本没碰数据库。转折点在文件服务器的一次例行巡检:一个不活跃的共享目录出现了新下载记录,顺着账号往下查,是一个弱口令的内部账号被撞库,而这个账号恰好对备份目录有读权限。拖走的是连续三十天的未加密归档,等于把库里三十天的全部增量明文端走了。
# 备份链路的自查三问,落到命令就是 ls -l /backup/ | head # 备份文件权限:除备份进程外无人可读? openssl enc -d -in day.bson.gz.enc -out /dev/null # 能否解密:密钥在 KMS 而非同机 grep -c download /srv/share/audit.log # 共享目录是否有非预期的读取
整改的关键认知是:备份的敏感度等于数据本身,且备份链路的安全性通常低于主库——它没有认证、没有 TLS、躺在便宜的旧机器上。修复动作包括备份归档一律加密且密钥与备份文件分离存放、备份目录取消共享改为推送式上传、文件服务器纳入与数据库同级的巡检清单。安全强度取决于最弱一环,而最弱一环几乎总是那条"临时搭一下"的链路。
TLS 与加密配置不是一次性的活,真正的成本在轮换。证书轮换要做到不停服:mongod 支持在线 reload 证书,逐节点滚动替换、每换一个节点确认复制健康,整套动作十分钟;怕的是没人记得证书还有三十天到期,所以证书有效期监控属于第 10 章告警清单的必选项。字段级加密的密钥管理同理:密钥放 KMS、按年轮换、旧密钥只解密不加密——三条做到,密钥泄露的爆炸半径才能被限制在单个周期内。
审计配置好只是开始,价值在出事后的十分钟里。标准流程:先用时间窗过滤 audit.json,锁定敏感动作;再按用户聚合,区分人肉账号与程序账号——程序账号在凌晨三点 dropCollection 几乎必是异常;最后把审计记录与变更工单对照,有工单的放行、没工单的升级。一次演练能把流程固化成脚本,出真事时才不会手忙脚乱。
// 用聚合从审计日志里捞出时间窗内的危险动作,按用户分组 db.getSiblingDB("admin").getCollection("audit").aggregate([ { $match: { atype: { $in: ["dropCollection", "dropDatabase", "authenticate"] }, ts: { $gte: new Date("2024-06-01T00:00:00Z") } } }, { $group: { _id: { user: "$users", atype: "$atype" }, n: { $sum: 1 } } }, { $sort: { n: -1 } } ]); // 输出示例:{ _id: { user: "reporter", atype: "authenticate" }, n: 4 } ← 报表服务深夜高频登录,可疑
网络隔离还有一个中间层常被跳过:内网不等于可信。实例之间、应用与 mongos 之间用安全组做白名单,只放行预期的来源,这一层挡住的是横向移动——一台被攻陷的应用服务器,不应顺路摸到数据库的备份节点与 config server。五道防线的本意正在于此:任何一道被突破,下一道还在。
最后把两节的六项基线变成上线前的一页检查单:bindIp 与安全组双确认、认证开启且账号分离、应用最小权限、节点间 TLS、备份加密且密钥分离、审计高危动作留痕。六项每季度抽查一次,抽查结果进容量与安全联席评审——安全与性能一样,是一次性建设加持续巡检的混合工程。