MongoDB安全与权限管理


四、MongoDB安全与权限管理

通常为了保证数据安全性,Redis、MySQL、MQ、ES……,通常都会配置账号/密码,一来可以提高安全等级,二来还可以针对不同库、操作设置权限,极大程度上降低了数据的安全风险。同样,在MongoDB中也支持创建账号、密码,以及分配权限,并且还支持角色的概念,可以先为角色分配权限,再为用户绑定角色,从而节省大量重复的权限分配工作。

同时,MongoDB中还内置了大量常用角色,方便于咱们快速分配权限,不过并没有默认的账号,所以想要启用MongoDB的访问控制,还需要先创建一个账号:

// 切换到admin数据库
use admin;
// 创建一个用户,并赋予root角色(root角色只能分配给admin库)
db.createUser({"user":"zhuzi", "pwd":"123456", "roles":["root"]});
// 退出mongosh客户端
quit;

接着再关闭MongoDB服务,重新启动时开启访问控制,必须使用账号密码连接才允许操作:

[root@~]# /usr/local/mongodb/bin/mongod -shutdown -f /usr/local/mongodb/conf/standalone/mongodb.conf
[root@~]# /usr/local/mongodb/bin/mongod -auth -f /usr/local/mongodb/conf/standalone/mongodb.conf
[root@~]# /usr/local/mongodb/mongosh/bin/mongosh 192.168.229.135:27017

或者这里也可以直接修改配置文件:

[root@~]# vi /usr/local/mongodb/conf/standalone/mongodb.conf

# 在配置文件结尾加上这两行
security:
    authorization: enabled

然后通过不带-auth的命令启动,效果同样是相同的。

接着先切换到咱们前面创建的zhuzi库,查询一下xiong_mao集合试试看:

use zhuzi;
db.xiong_mao.find({_id:1});
MongoServerError: command find requires authentication

此时就会看到对应报错,提示目前未授权,所以无法执行命令,因此这里需要登录一下,不过登录必须要切换到admin库下才可以,否则会提示认证失败:

db.auth("zhuzi","123456");
{ok:1}

use zhuzi;
db.xiong_mao.find({_id:1});
[{_id:1,name:'肥肥',age:3,hobby:'竹子',color:'黑白色'} ]

认证成功后,再次切回zhuzi库查询,此时会发现数据依旧可以查询出来。

当然,如果不想每次连接时都切换到admin库下登录,然后再切换回来,此时可以在zhuzi库下再创建一个用户,如下:

// 先切换到zhuzi库
use zhuzi;

// 再在zhuzi库下创建一个zhuzi用户,并分配dbOwner角色
db.createUser({"user":"zhuzi", "pwd":"123456", "roles":[{"role":"dbOwner", "db":"zhuzi"}]});

// 退出连接
quit;

然后可以再次连接MongoDB服务,这时直接切换到zhuzi库下登录后,也照样可以读写数据,而关于上述命令中分配的dbOwner角色是什么意思呢?后面会说明。

4.1、MongoDB内置角色

前面大致了解了一下如何启用访问控制后,接着来看看MongoDB中的内置角色,毕竟前面只使用了root角色,可以通过下述命令来查询MongoDB所有内置角色:

use admin;
db.runCommand({rolesInfo: 1, showBuiltinRoles: true});

返回结果较长,这里就不贴了,大家可以自己执行一下,这里归类一下:

root:超级管理员权限,可以执行任何操作;

read:只读用户,不允许对数据库执行写入操作;

readWrite:读写用户,允许对数据执行读写操作;

dbAdmin:数据库管理员(如创建和删除数据库),不允许读写数据;

userAdmin:用户管理员(如创建和删除用户),不允许读写数据;

dbOwner:同时拥有dbAdmin、userAdmin两个角色的权限,且允许读写数据;

backup:具有备份和恢复权限,不允许读写数据;

restore:只具有数据恢复权限,不允许读写数据;

clusterAdmin:集群超级管理员,可以执行集群中任意操作,允许读写数据;

clusterManager:集群管理员,只可以管理集群节点、配置等;

clusterMonitor:集群监视员,允许监控集群的状态和性能,不允许读写数据;

上面是一些常用的角色,而对于其他使用频率较少的则不再列出,而这些内置角色,可以在创建用户的时候分配,一个用户同时可以绑定多个角色。但如果你想要的权限,内置角色并不提供,也可以自定义角色,下面来看看。

4.2、MongoDB自定义角色

先来看看自定义角色的语法:

use zhuzi;

db.createRole(
{
// 自定义角色的名称
role:"zhuziRole",
// 自定义角色拥有的权限集
privileges:[
{
// 自定义角色可操作的资源 
resource:
{
// 当前角色可操作zhuzi库
db:"zhuzi",
// 当前角色具体可操作的集合(多个传数组,所有写"")
collection:""
},
// 当前角色拥有的权限
actions:["find","update","insert","remove"]
}
],
// 当前角色是否继承其他角色,如果指定了其他角色,当前角色自动继承父亲的所有权限
roles:[]
}
);

关于该命令中的具体含义,大家可以参考上面的注释,通过该方式,诸位可以灵活的创建出各种适用于业务的角色,最后再附上一些相关命令:

// 给指定角色增加权限
db.grantPrivilegesToRole(
"角色名称",
[{
resource:{
db:"库名",
collection:""
},
actions:["权限1","……"]
}]
);

// 回收指定角色的权限
db.revokePrivilegesFromRole(
"角色名称",
[{
resource:{
db:"库名",
collection:""
},
actions:["权限1","……"]
}]
);

// 删除角色(要先进入角色所在的库)
use zhuzi;
db.dropRole("角色名称");

// 查看当前库的所有角色
show roles;

// 查看当前库中所有用户
show users;

OK,掌握上述这些命令完全能满足日常需求了,至于其他更多的,则可以参考官网或自行查阅资料。