外观
MongoDB 用户与角色管理
基于角色的访问控制(RBAC)
MongoDB 使用基于角色的访问控制(Role-Based Access Control,RBAC)来管理用户对数据库资源的访问权限。RBAC 模型将权限分配给角色,然后将角色分配给用户,实现了权限的集中管理和精细控制。
RBAC 核心概念
- 用户(User):数据库的访问主体,通过用户名和密码进行认证
- 角色(Role):一组权限的集合,定义了用户可以执行的操作
- 权限(Privilege):定义了对特定资源的操作权限,包括资源类型和操作类型
- 资源(Resource):数据库对象,如数据库、集合、集合集或集群
- 操作(Action):对资源可以执行的操作,如查询、插入、更新、删除等
内置角色
MongoDB 提供了多种内置角色,涵盖了从集群管理到数据库操作的各种权限需求。内置角色可以分为以下几类:
1. 数据库用户角色
| 角色名称 | 描述 |
|---|---|
read | 允许用户读取指定数据库中的数据 |
readWrite | 允许用户读取和写入指定数据库中的数据 |
2. 数据库管理角色
| 角色名称 | 描述 |
|---|---|
dbAdmin | 允许用户执行数据库管理任务,如索引创建、统计信息查看等 |
dbOwner | 数据库所有者,拥有 readWrite、dbAdmin 和 userAdmin 权限 |
userAdmin | 允许用户管理指定数据库中的用户和角色 |
3. 集群管理角色
| 角色名称 | 描述 |
|---|---|
clusterAdmin | 集群管理员,拥有 clusterManager、clusterMonitor 和 hostManager 权限 |
clusterManager | 允许用户管理集群配置,如分片、复制集等 |
clusterMonitor | 允许用户监控集群状态 |
hostManager | 允许用户管理服务器,如关闭、重启等 |
4. 备份恢复角色
| 角色名称 | 描述 |
|---|---|
backup | 允许用户执行备份操作 |
restore | 允许用户执行恢复操作 |
5. 超级用户角色
| 角色名称 | 描述 |
|---|---|
root | 超级用户,拥有所有权限 |
6. 其他角色
| 角色名称 | 描述 |
|---|---|
__system | 内部角色,用于 MongoDB 系统进程 |
用户管理
1. 创建用户
bash
# 切换到 admin 数据库
use admin
# 创建管理员用户
db.createUser({
user: "admin",
pwd: "password",
roles: [
{ role: "root", db: "admin" }
]
})
# 在指定数据库中创建用户
use mydatabase
db.createUser({
user: "myuser",
pwd: "mypassword",
roles: [
{ role: "readWrite", db: "mydatabase" },
{ role: "read", db: "otherdatabase" }
]
})2. 查看用户
bash
# 查看当前数据库中的用户
db.getUsers()
# 查看指定数据库中的用户
use admin
db.getUsers()
# 查看特定用户
db.getUser("admin")3. 修改用户密码
bash
# 修改当前数据库中用户的密码
db.changeUserPassword("myuser", "newpassword")
# 使用 updateUser 修改密码
db.updateUser("myuser", { pwd: "newpassword" })4. 修改用户角色
bash
# 修改用户角色
db.updateUser("myuser", {
roles: [
{ role: "readWrite", db: "mydatabase" },
{ role: "dbAdmin", db: "mydatabase" }
]
})5. 删除用户
bash
# 删除当前数据库中的用户
db.dropUser("myuser")
# 删除指定数据库中的用户
use admin
db.dropUser("admin")角色管理
1. 创建自定义角色
bash
# 创建自定义角色
db.createRole({
role: "myCustomRole",
privileges: [
{ resource: { db: "mydatabase", collection: "mycollection" }, actions: ["find", "insert", "update"] },
{ resource: { db: "mydatabase", collection: "system.js" }, actions: ["find"] }
],
roles: [
{ role: "read", db: "otherdatabase" }
]
})2. 查看角色
bash
# 查看当前数据库中的所有角色
db.getRoles()
# 查看指定数据库中的角色
use admin
db.getRoles()
# 查看特定角色的详细信息
db.getRole("myCustomRole", { showPrivileges: true })3. 修改自定义角色
bash
# 修改自定义角色
db.updateRole("myCustomRole", {
privileges: [
{ resource: { db: "mydatabase", collection: "mycollection" }, actions: ["find", "insert", "update", "remove"] },
{ resource: { db: "mydatabase", collection: "system.js" }, actions: ["find"] }
],
roles: [
{ role: "read", db: "otherdatabase" }
]
})4. 删除自定义角色
bash
# 删除自定义角色
db.dropRole("myCustomRole")权限管理
1. 权限资源
权限资源可以是以下类型:
- 集群(Cluster):整个 MongoDB 集群
- 数据库(Database):指定数据库
- 集合(Collection):指定数据库中的指定集合
- 集合集(Collection Set):指定数据库中的多个集合
- 任意资源(Any Resource):所有资源
2. 权限操作
权限操作包括:
- 查询操作:
find,aggregate,distinct等 - 写入操作:
insert,update,remove等 - 管理操作:
createIndex,dropIndex,createCollection等 - 集群操作:
addShard,removeShard,replSetReconfig等
3. 权限示例
bash
# 授予用户对集合的所有权限
db.grantPrivilegesToRole("myRole", [
{ resource: { db: "mydb", collection: "mycoll" }, actions: ["find", "insert", "update", "remove"] }
])
# 撤销用户对集合的权限
db.revokePrivilegesFromRole("myRole", [
{ resource: { db: "mydb", collection: "mycoll" }, actions: ["remove"] }
])认证机制
1. 启用认证
要启用 MongoDB 的认证机制,需要在配置文件中设置:
yaml
security:
authorization: enabled或者在启动时指定 --auth 参数:
bash
mongod --auth --config /etc/mongod.conf2. 用户认证
bash
# 使用 mongo 客户端认证
mongo -u admin -p password --authenticationDatabase admin
# 在 mongo shell 中认证
use admin
db.auth("admin", "password")
# 使用连接字符串认证
mongo "mongodb://admin:password@localhost:27017/admin"3. 复制集认证
对于复制集,需要配置密钥文件或证书认证:
yaml
security:
clusterAuthMode: keyFile
keyFile: /etc/mongodb/keyfile最佳实践
1. 最小权限原则
- 为用户分配最小必要的权限
- 避免使用
root或dbOwner等高级角色,除非必要 - 为不同的用户分配不同的角色,根据其工作职责
2. 管理员用户管理
- 创建专门的管理员用户,用于管理其他用户和角色
- 不要将管理员用户用于普通应用访问
- 定期轮换管理员密码
- 限制管理员用户的访问IP
3. 应用用户管理
- 为每个应用创建独立的用户
- 根据应用需求分配适当的角色
- 定期轮换应用用户密码
- 使用环境变量或密钥管理系统存储密码
4. 角色设计
- 合理设计自定义角色,避免权限过大
- 定期审查角色权限,确保符合业务需求
- 使用角色继承,减少重复配置
5. 审计与监控
- 启用审计日志,记录用户的认证和授权操作
- 监控用户活动,检测异常行为
- 定期审查用户列表,清理不再使用的用户
6. 密码策略
- 使用强密码,包含大小写字母、数字和特殊字符
- 定期轮换密码
- 避免在代码中硬编码密码
- 使用 TLS/SSL 加密传输密码
常见问题与解决方案
问题:忘记管理员密码
解决方案:
- 关闭 MongoDB 服务
- 以无认证模式启动 MongoDB:bash
mongod --noauth --config /etc/mongod.conf - 连接到 MongoDB 并重置管理员密码:bash
mongo use admin db.changeUserPassword("admin", "newpassword") - 关闭 MongoDB 服务,重新以认证模式启动
问题:用户无法访问指定数据库
解决方案:
- 检查用户是否具有访问该数据库的角色
- 检查用户认证时使用的数据库是否正确
- 检查角色的权限是否包含对该数据库的操作
- 使用
db.getUser()查看用户的详细信息和角色
问题:自定义角色权限不生效
解决方案:
- 检查角色的权限资源是否正确
- 检查角色的操作是否包含所需的操作
- 检查用户是否已被正确分配该角色
- 使用
db.getRole()查看角色的详细权限
问题:复制集认证失败
解决方案:
- 检查密钥文件是否存在,权限是否为 600
- 检查所有复制集成员使用的密钥文件是否相同
- 检查
clusterAuthMode配置是否正确 - 查看 MongoDB 日志,获取详细的错误信息
常见问题(FAQ)
Q1: MongoDB 中的 read 角色和 readWrite 角色有什么区别?
A1: read 角色允许用户读取指定数据库中的数据,包括执行 find、aggregate 等查询操作;readWrite 角色在 read 角色的基础上,还允许用户执行写入操作,如 insert、update、remove 等。
Q2: 如何限制用户只能访问特定集合?
A2: 可以通过创建自定义角色,指定资源为特定集合,并授予相应的操作权限。例如:
bash
db.createRole({
role: "myCollectionRole",
privileges: [
{ resource: { db: "mydb", collection: "mycoll" }, actions: ["find"] }
],
roles: []
})Q3: MongoDB 支持基于 IP 的访问控制吗?
A3: MongoDB 本身不直接支持基于 IP 的访问控制,但可以通过配置操作系统防火墙或使用 MongoDB Atlas 等托管服务来实现。例如,使用 iptables 限制 MongoDB 端口的访问 IP。
Q4: 如何查看用户的详细权限?
A4: 可以使用 db.getUser() 命令查看用户的详细信息,包括角色和权限:
bash
db.getUser("myuser", { showPrivileges: true, showCredentials: true })Q5: 如何在应用中安全地存储 MongoDB 密码?
A5: 推荐使用环境变量、密钥管理系统(如 AWS KMS、HashiCorp Vault)或配置文件加密来存储 MongoDB 密码,避免在代码中硬编码密码。在连接 MongoDB 时,从这些安全存储中获取密码。
