MongoDB 的用户和角色权限简介:
默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随意连接到实例进行各种操作,MongoDB不会对连接客户端进行用户验证,这是非常危险的。
为了能保障mongodb的安全可以做以下几个步骤:
1)使用新的端口,默认的27017端口如果一旦知道了ip就能连接上,不太安全。
2)设置mongodb的网络环境,最好将mongodb部署到公司服务器内网,这样外网是访问不到的。公司内部访问使用vpn等。
3)开启安全认证。认证要同时设置服务器之间的内部认证方式,同时要设置客户端连接到集群的账号密码认证方式。
为了强制开启用户访问控制(用户验证),则需要在MongoDB实例启动时使用选项 -- auth 或在指定启动配置文件中添加选项 auth=true 。
1)启用访问控制:
MongoDB使用的是基于角色的访问控制(Role-Based Access Control,RBAC)来管理用户对实例的访问。
通过对用户授予一个或多个角色来控制用户访问数据库资源的权限和数据库操作的权限,在对用户分配角色之前,用户无法访问实例。
在实例启动时添加选项 -- auth 或指定启动配置文件中添加选项 auth=true 。
2)角色:
在MongoDB中通过角色对用户授予相应数据库资源的操作权限,每个角色当中的权限可以显式指定,也可以通过继承其他角色的权限,或者两者都存在的权限。
3)权限:
权限由指定的数据库资源(resource)以及允许在指定资源上进行的操作(action)组成。
1. 资源(resource)包括:数据库、集合、部分集合和集群;
2. 操作(action)包括:对资源进行的增、删、改、查(CRUD)操作。
在角色定义时可以包含一个或多个已存在的角色,新创建的角色会继承包含的角色所有的权限。在同一个数据库中,新创建角色可以继承其他角色的权限,在 admin 数据库中创建的角色可以继承在其它任意数据库中角色的权限。
常用的内置角色:
数据库用户角色: read、readWrite;
所有数据库用户角色: readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
数据库管理角色: dbAdmin、dbOwner、userAdmin;
集群管理角色: clusterAdmin、clusterManager、clusterMonitor、hostManager;
备份恢复角色: backup、restore;
超级用户角色: root
内部角色: system
角色说明:
单实例环境:
对单实例的MongoDB服务开启安全认证,这里的单实例指的是未开启副本集或分片的MongoDB实例。
1.先停止已开启的服务
2.添加用户和权限
登录Mongo客户端:./mongo --host 192.168.43.182 --port 27017
创建两个管理员用户,一个是系统的超级管理员 root ,一个是admin库的管理用户 admin
切换到admin库:use admin
创建系统超级用户 root,设置密码 root,设置角色root:
db.createUser({ user:"root", pwd:"root", roles:["root"] })
创建专门用来管理admin库的账号 admin,只用来作为用户权限的管理
db.createUser({ user: "admin", pwd: "admin", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] })
查看已经创建了的用户的情况:db.system.users.find()
删除用户:db.dropUser("admin")
修改密码:db.changeUserPassword("root", "123456")
提示:
1)案例中创建了两个用户,分别对应超管和专门用来管理用户的角色,事实上,你只需要一个用户即可。如果你对安全要求很高,防止超管泄漏,则不要创建超管用户。
2)和其它数据库(MySQL)一样,权限的管理都差不多一样,也是将用户和权限信息保存到数据库对应的表中。Mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名、密码和数据库信息。
3)如果不指定数据库,则创建的指定的权限的用户在所有的数据库上有效,如 {role:"userAdminAnyDatabase", db:""}
认证测试:
切换到admin:use admin
验证:db.auth("root","root")
创建普通用户:
创建普通用户可以在没有开启认证的时候添加,也可以在开启认证之后添加,但开启认证之后,必须使用有操作admin库的用户登录认证后才能操作。
底层都是将用户信息保存在了admin数据库的集合system.users中。
1.创建(切换)将来要操作的数据库articledb:use articledb
2.创建用户,拥有articledb数据库的读写权限readWrite,密码是123456
db.createUser({ user: "bobo", pwd: "123456", roles: [{ role: "readWrite", db: "articledb" }] })
3.测试是否可用:db.auth("bobo","123456")
3.服务端开启认证和客户端连接登录
前面虽然设置了用户,但是没有开启认证,用户没有起作用
1)关闭已经启动的服务
ps -ef | grep mongo kill 35606
2)以开启认证的方式启动服务
有两种方式开启权限认证启动服务:一种是参数方式,一种是配置文件方式。
参数方式:在启动时指定参数 -- auth
./mongod -f /mongodb/single/mongod.conf --auth
配置文件方式:在mongod.conf配置文件中加入 vim /mongodb/single/mongod.conf
security:
#开启授权认证
authorization: enabled
启动:./mongod -f /mongodb/single/mongod.conf
开启了认证的情况下的客户端登录
有两种认证方式,一种是先登录,在mongo shell中认证;一种是登录时直接认证。
1)先连接再认证:./mongo --host 192.168.43.182 --port 27017 db.auth("root", "root");
2)连接时直接认证
./mongo --host 192.168.43.182 --port 27017 --authenticationDatabase articledb -u bobo -p 123456
use articledb(必须先切换数据库才能接下来的操作,因为bobo用户只有articledb读写权限) db.comment.find();
副本集环境:
对于搭建好的mongodb副本集,为了安全,启动安全认证,使用账号密码登录。
对副本集执行访问控制需要配置两个方面 :
1)副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书。密钥文件比较简单,本文使用密钥文件,官方推荐如果是测试环境可以使用密钥文件,但是正式环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问
2)使用客户端连接到mongodb集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。
在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。
通过主节点添加一个管理员帐号:
只需要在主节点上添加用户,副本集会自动同步。
开启认证之前,创建超管用户:root,密码:root
use admin
db.createUser({ user:"root", pwd:"root", roles:["root"] })
创建副本集认证的key文件:
生成一个key文件到当前文件夹中。
可以使用任何方法生成密钥文件。例如,以下操作使用openssl生成密码文件,然后使用chmod来更改文件权限,仅为文件所有者提供读取权限
openssl rand -base64 90 -out ./mongo.keyfile chmod 400 ./mongo.keyfile
注意:所有副本集节点都必须要用同一份keyfile,一般是在一台机器上生成,然后拷贝到其他机器上,且必须有读的权限,否则将来会报错
文件位置随便。但是为了方便查找,建议每台机器都放到一个固定的位置,都放到和配置文件一起的目录中。
cp mongo.keyfile /mongodb/replica_sets/myrs_27017
cp mongo.keyfile /mongodb/replica_sets/myrs_27018
cp mongo.keyfile /mongodb/replica_sets/myrs_27019
修改配置文件指定keyfile:
分别编辑几个服务的mongod.conf文件,添加相关内容:
/mongodb/replica_sets/myrs_27017/mongod.conf
security: #KeyFile鉴权文件 keyFile: /mongodb/replica_sets/myrs_27017/mongo.keyfile #开启认证方式运行 authorization: enabled
/mongodb/replica_sets/myrs_27018/mongod.conf
security: #KeyFile鉴权文件 keyFile: /mongodb/replica_sets/myrs_27018/mongo.keyfile #开启认证方式运行 authorization: enabled
/mongodb/replica_sets/myrs_27019/mongod.conf
security: #KeyFile鉴权文件 keyFile: /mongodb/replica_sets/myrs_27019/mongo.keyfile #开启认证方式运行 authorization: enabled
重新启动副本集:
如果副本集是开启状态,则先分别关闭副本集中的每个mongod,从次节点开始。直到副本集的所有成员都离线,包括任何仲裁者。主节点必须是最后一个成员关闭以避免潜在的回滚。
kill -2 36984 37070 36920
分别启动副本集节点:
./mongod -f /mongodb/replica_sets/myrs_27017/mongod.conf
./mongod -f /mongodb/replica_sets/myrs_27018/mongod.conf
./mongod -f /mongodb/replica_sets/myrs_27019/mongod.conf
在主节点上添加普通账号,会自动同步账号到从节点:
use admin db.auth("root","root")
use articledb db.createUser({user: "bobo", pwd: "123456", roles: ["readWrite"]})
重新连接,使用普通用户 bobo重新登录,查看数据。
分片集群环境:
和副本集环境基本一致,在路由、配置、分片的所有副本中都要存一份认证的keyfile文件,在每个副本配置文件中都要指定keyfile和开启认证。