第十一章:安全配置
最后更新: 2024-01-01
作者: MongoDB Team
页面目录
第十一章:安全配置
MongoDB 安全机制与访问控制
11.1 安全概述
┌─────────────────────────────────────────────────────────────────┐
│ MongoDB 安全层级 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 网络层安全 ││
│ │ - TLS/SSL 加密 ││
│ │ - IP 白名单 ││
│ │ - VPN/专用网络 ││
│ └─────────────────────────────────────────────────────────────┘│
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 认证机制 ││
│ │ - SCRAM 认证 (默认) ││
│ │ - x.509 证书认证 ││
│ │ - LDAP 认证 (企业版) ││
│ │ - Kerberos 认证 (企业版) ││
│ └─────────────────────────────────────────────────────────────┘│
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 授权机制 ││
│ │ - 基于角色的访问控制 (RBAC) ││
│ │ - 内置角色 ││
│ │ - 自定义角色 ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────┘
11.2 认证配置
启用 SCRAM 认证
# mongod.conf
security:
authorization: enabled
# 重启服务
sudo systemctl restart mongod
创建用户
// 连接到 MongoDB(需要认证)
mongosh -u admin -p password --authenticationDatabase admin
// 创建管理员用户
use admin
db.createUser({
user: "admin",
pwd: "strong_password",
roles: [
{ role: "root", db: "admin" }
]
})
// 创建应用用户
use admin
db.createUser({
user: "app_user",
pwd: "app_password",
Mechanisms: ["SCRAM-SHA-256"], // 强制使用 SCRAM-SHA-256
roles: [
{ role: "readWrite", db: "app_database" },
{ role: "dbAdmin", db: "app_database" }
]
})
// 创建只读用户
db.createUser({
user: "readonly_user",
pwd: "readonly_password",
roles: [
{ role: "read", db: "app_database" }
]
})
连接认证
# 命令行认证
mongosh -u username -p password --authenticationDatabase admin
# 指定认证数据库
mongosh -u username -p password --authenticationDatabase myauthdb
# 多用户切换
db.auth("username", "password")
11.3 x.509 证书认证
生成证书
# 生成 CA 证书
openssl req -new -x509 -days 3650 -nodes \
-out mongodb-ca.crt \
-keyout mongodb-ca.key \
-subj "/CN=mongodb-ca/O=MongoDB"
# 生成服务器证书
openssl req -new -nodes -newkey rsa:2048 \
-keyout mongodb-server.key \
-out mongodb-server.csr \
-subj "/CN=mongodb-server"
# 签署服务器证书
openssl x509 -req -days 365 -CA mongodb-ca.crt \
-CAkey mongodb-ca.key -CAcreateserial \
-in mongodb-server.csr \
-out mongodb-server.crt
# 合并证书
cat mongodb-server.crt mongodb-server.key > mongodb-server.pem
# 生成客户端证书
openssl req -new -nodes -newkey rsa:2048 \
-keyout mongodb-client.key \
-out mongodb-client.csr \
-subj "/CN=mongodb-client"
openssl x509 -req -days 365 -CA mongodb-ca.crt \
-CAkey mongodb-ca.key -CAcreateserial \
-in mongodb-client.csr \
-out mongodb-client.crt
cat mongodb-client.crt mongodb-client.key > mongodb-client.pem
配置 x.509 认证
# mongod.conf
net:
port: 27017
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongodb-server.pem
CAFile: /etc/ssl/mongodb-ca.crt
allowConnectionsWithoutCertificates: false
security:
clusterAuthMode: x509
authorization: enabled
使用 x.509 连接
# 连接时使用客户端证书
mongosh --ssl --sslCAFile mongodb-ca.crt \
--sslPEMKeyFile mongodb-client.pem \
--host mongodb-server
11.4 基于角色的访问控制 (RBAC)
内置角色
| 角色 | 权限 |
|---|---|
| 数据库用户角色 | |
read |
读取集合数据 |
readWrite |
读写集合数据 |
| 数据库管理角色 | |
dbAdmin |
管理索引、统计信息 |
dbOwner |
readWrite + dbAdmin + userAdmin |
userAdmin |
管理用户和角色 |
| 集群管理角色 | |
clusterAdmin |
所有集群管理权限 |
clusterManager |
集群监控和管理 |
clusterMonitor |
只读集群监控 |
hostManager |
管理主机 |
| 备份/恢复角色 | |
backup |
备份数据 |
restore |
恢复数据 |
| 超级用户角色 | |
root |
所有权限 |
__system |
MongoDB 内部使用 |
集合级别权限
// 只读特定集合
db.createRole({
role: "analyticsReader",
privileges: [
{
resource: { db: "app", collection: "orders" },
actions: ["find"]
},
{
resource: { db: "app", collection: "products" },
actions: ["find"]
}
],
roles: []
})
// 读写特定集合
db.createRole({
role: "orderManager",
privileges: [
{
resource: { db: "app", collection: "orders" },
actions: ["find", "insert", "update", "remove"]
}
],
roles: []
})
用户角色管理
// 创建具有自定义角色的用户
db.createUser({
user: "analytics_user",
pwd: "analytics_password",
roles: [
{ role: "analyticsReader", db: "app" },
{ role: "read", db: "reporting" }
]
})
// 查看用户权限
db.getUser("app_user")
// 查看角色权限
db.getRole("analyticsReader", { showPrivileges: true })
// 修改用户角色
db.grantRolesToUser("app_user", [
{ role: "readWrite", db: "app_database" }
])
// 移除用户角色
db.revokeRolesFromUser("app_user", [
{ role: "read", db: "app_database" }
])
// 修改密码
db.changeUserPassword("app_user", "new_strong_password")
角色管理
// 创建自定义角色
db.createRole({
role: "customRole",
privileges: [
{
resource: { db: "app", collection: "" },
actions: ["find", "insert", "update"]
},
{
resource: { db: "admin", collection: "" },
actions: ["serverStatus"]
}
],
roles: []
})
// 查看所有角色
db.adminCommand({ rolesInfo: 1, showPrivileges: true })
// 删除角色
db.dropRole("customRole")
// 授予角色权限
db.grantPrivilegesToRole("customRole", [
{
resource: { db: "app", collection: "logs" },
actions: ["find"]
}
])
// 撤销角色权限
db.revokePrivilegesFromRole("customRole", [
{
resource: { db: "app", collection: "logs" },
actions: ["find"]
}
])
11.5 网络安全
绑定 IP
# mongod.conf
net:
bindIp: 127.0.0.1,10.0.0.100
# 或绑定所有接口(仅用于内网)
# bindIpAll: true
防火墙配置
# Ubuntu/Debian (ufw)
sudo ufw allow from 10.0.0.0/24 to any port 27017
sudo ufw deny 27017
# RHEL/CentOS (firewalld)
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4" source address="10.0.0.0/24" port port="27017" protocol="tcp" accept
'
sudo firewall-cmd --reload
内部认证
# mongod.conf (副本集/分片集群节点)
security:
keyFile: /etc/mongodb/keyfile
authorization: enabled
# 生成 keyfile
openssl rand -base64 756 > /etc/mongodb/keyfile
chmod 400 /etc/mongodb/keyfile
11.6 审计配置
启用审计
# mongod.conf (企业版)
security:
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.log
filter: '{ atype: { $in: ["createUser", "dropUser", "updateUser"] } }'
审计输出选项
# 输出到 syslog
security:
auditLog:
destination: syslog
syslogFacility: local0
# 输出到控制台
security:
auditLog:
destination: console
# 输出到 MongoDB Atlas (云端)
security:
auditLog:
destination: mongodb-atlas
11.7 字段级安全
使用投影限制字段
// 只返回允许的字段
db.users.find(
{ _id: userId },
{ password: 0, sensitive_data: 0 }
)
加密字段(企业版)
// 创建加密集合
db.createCollection("customers", {
encryptedFields: [
{ fieldName: "ssn", bsonType: "string" },
{ fieldName: "creditCard", bsonType: "string" }
]
})
// 配置加密
db.adminCommand({
configureQueryableEncryption: {
kms: {
local: { key: BinData(0, "your-32-byte-key") }
},
encryptedFields: "customers",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
})
💡 实践提示
- 启用访问控制:生产环境必须启用
--auth - 最小权限原则:只为用户分配所需的最小权限
- 强密码策略:使用 SCRAM-SHA-256 和强密码
- 网络隔离:使用防火墙限制访问源
- 定期轮换:定期更换密钥和密码
- 审计日志:启用审计跟踪关键操作
📚 继续学习