MongoDB 安全加固实战:未授权访问防护与数据加密配置指南

适用场景

MongoDB 安全加固适用于以下场景:数据库实例直接暴露在公网导致未授权访问;业务增长后忘记为实例开启认证,任何人均可通过 mongo shell 直连并读取、篡改数据;等保 2.0 或金融行业合规要求对数据库访问链路做加密与审计。本文从 MongoDB 未授权访问原理出发,给出开启认证、配置访问控制、启用 TLS 加密与安全基线加固的完整方案。

前置条件

  • 一台已安装 MongoDB 的服务器(本文以 MongoDB 6.0/7.0 社区版为例)
  • 拥有 MongoDB 配置文件 /etc/mongod.conf 的读写权限
  • 能通过 SSH 登录服务器,并已配置防火墙(如 iptables 或云安全组)

原理说明

MongoDB 未授权访问的本质是认证开关未开启:默认配置下服务端不校验客户端身份,任何能连通 27017 端口的 IP 都可以以管理员权限直连数据库,配合 db.adminCommand({listDatabases:1}) 即可枚举全部库表,进而拖库或加密勒索。MongoDB 的认证体系基于 SCRAM-SHA-256 机制,启用后客户端需提供用户名与密码,由服务端完成口令校验。同时,MongoDB 通过 角色(Role) 控制权限粒度,最小权限原则要求业务账号只拥有其所需库的读写权限。若数据库需跨公网传输数据,还必须在传输层启用 TLS 加密,防止口令与数据被中间人截获。

操作步骤

1. 创建管理员账号

# 先以无认证模式临时启动,或直接用本地 shell 连接
mongosh --port 27017

# 切换 admin 库创建超级管理员
use admin
db.createUser({
  user: "admin",
  pwd: passwordPrompt(),   # 交互输入强密码
  roles: [{ role: "root", db: "admin" }]
})

关键参数roles: "root" 赋予所有库的管理权限,仅用于初始化,业务运行期建议改用 readWrite 等受限角色。

2. 开启认证并绑定内网地址

# 编辑 /etc/mongod.conf
security:
  authorization: enabled   # 开启认证

net:
  port: 27017
  bindIp: 127.0.0.1,192.168.1.10   # 仅绑定本机与内网 IP,禁止 0.0.0.0

# 重启生效
sudo systemctl restart mongod

关键参数bindIp 绝不能配置 0.0.0.0,否则等于把数据库裸奔在公网;authorization: enabled 是阻断未授权访问的核心开关。

3. 验证未授权访问已被阻断

# 未提供凭据直连,应报认证错误
mongosh --host 192.168.1.10 --port 27017
# 输出: MongoServerError: Unauthorized

# 使用账号密码登录成功
mongosh --host 192.168.1.10 --port 27017 -u admin -p --authenticationDatabase admin

4. 启用 TLS 加密传输

# 生成自签名证书(生产环境建议使用 CA 签发)
openssl req -newkey rsa:2048 -nodes -keyout mongodb.key -x509 -days 365 -out mongodb.crt
cat mongodb.key mongodb.crt > mongodb.pem

# 修改 mongod.conf
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/mongodb.pem

sudo systemctl restart mongod

# 客户端加密连接
mongosh "mongodb://192.168.1.10:27017/admin?tls=true" -u admin -p

5. 安全基线加固

# 关闭 HTTP 接口(老版本 Web 管理端口,默认已移除)
# 通过 iptables 仅放行内网访问 27017
sudo iptables -A INPUT -p tcp --dport 27017 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27017 -j DROP

# 定期备份并在备份时加密
dump --out /backup/mongo_$(date +%F) --authenticationDatabase admin -u admin -p

配置验证

# 1. 检查认证是否生效:无凭据连接应被拒绝
mongosh --host 127.0.0.1 --port 27017 --eval "db.runCommand({connectionStatus:1})"

# 2. 检查监听地址,不应出现 0.0.0.0
sudo ss -tlnp | grep 27017

# 3. 验证最小权限:用只读账号执行写操作应被拒绝
mongosh -u readonly -p --authenticationDatabase appdb --eval "db.users.insert({x:1})"
# 输出: MongoServerError: not authorized on appdb to execute command

常见问题

Q1:开启认证后应用连接报 Unauthorized,如何处理?

先确认应用连接串是否正确携带 authSource(认证库)参数,例如 mongodb://user:pass@host:27017/appdb?authSource=admin。其次检查账号所属库与角色,若账号在 admin 库创建,authSource 必须为 admin。最后确认连接用户名密码无多余空格。

Q2:开启 TLS 后老客户端连不上怎么办?

TLS 模式 requireTLS 强制所有连接加密,老版本驱动需升级支持 TLS 的版本,或在驱动连接串追加 ?tls=true&tlsAllowInvalidCertificates=true(仅测试环境,生产建议使用受信任 CA 证书)。若业务无法立即改造,可先用 preferTLS 过渡,但需尽快切换到强制加密。

总结

MongoDB 未授权访问是最常见的数据库失陷入口之一,开启 authorization: enabled、将 bindIp 限制在内网、启用 TLS 加密三件事能挡住绝大多数攻击路径。再配合最小权限账号、iptables 端口管控与加密备份,即可形成数据库层的纵深防御。建议每季度复查一次角色权限与连接审计日志。