MongoDB自定义用户权限

MongoDB自定义用户权限

  • 前言
  • mongodb用户权限介绍
    • 系统内置权限
    • 自定义权限
  • 实现自定义用户权限

前言

最近接手运维公司的mongo数据库,虽然之前对mongo有一点点的使用,但真正能够cover公司的mongo,还是有一定的挑战,平时也是边学习边运维。前一阵子对于mongo做了两件事,第一个是实现一个冷备系统,第二个是对mongo权限的收敛,本章主要介绍一下mongo权限(mongo版本3.2),以及如何实现自定义的用户权限。

mongodb用户权限介绍

mongodb用户权限分为内置权限和自定义权限,一般我们使用的read、readWrite、root等,都是系统内置的权限;mongo的用户权限,主要由角色名、适用范围、行为集合构成;下面简单介绍一下:

系统内置权限

类型 权限 适用库 官方简单说明
database user roles read - 当前库的只读权限,不包括system集合
database user roles readWrite - 读权限之上,加入了modify data的权限,不包括system集合
database admin roles dbAdmin - 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计,但不会有用户和权限管理的功能
database admin roles dbOwner - 在库中可以做任何操作,包括readWrite,dbAdmin,userAdmin
database admin roles userAdmin - 可以给当前库添加用户和权限
cluster admin roles clusteradmin admin 最大的集群管理权限,包括clustermanager、clustermonitor、hostmanager权限以及删除库的权限
cluster admin roles clustermanager admin 提供管理和监控集群的权限,包括config、local库
cluster admin roles clustermonitor admin 提供只读情况下使用集群监控工具的权限
cluster admin roles hostmanager admin 监控和管理servers
all database roles readAnyDatabase admin 可以读所有的库,除了local库和config库,也包括了listDatabases命令;3.4之后的版本允许访问local库和config库
all database roles readWriteAnyDatabase admin 同上,不同的是权限是readWrite
all database roles userAdminAnyDatabase admin 同上,不同的是权限是userAdmin
super roles root admin 超级用户,土皇帝,结合了all database roles类型的所有权限,以及clusterAdmin、restore、backup权限

自定义权限

命令: db.createRole()
范围:在admin库创建的role,可以被其他db使用
语法:

{ createRole: "",
  privileges: [
    { resource: {  }, actions: [ "", ... ] },
    ...
  ],
  roles: [
    { role: "", db: "" } | "",
    ...
  ],
  authenticationRestrictions: [
    {
      clientSource: ["" | "", ...],
      serverAddress: ["" | "", ...]
    },
    ...
  ],
  writeConcern: 
}

createRole : 角色名,string
privileges :特权,array,每个元素包括如下:

  • resource : 影响范围,{db:database, collection:collection} 或 {cluster:true};
  • actions:行为集合,[action1,action2,…],列举一些重要的action
action 说明
find
insert
remove
update
createCollection
createIndex
createRole
createUser
dropCollection
dropRole
dropUser
grantRole
viewRole 查看角色
viewUser
dropDatabase
dropIndex
renameCollectionSameDB
convertToCapped 将已存在的、非固定的集合转变成固定集合
其他权限请自行查看官方文档
  • roles:需要从哪个role继承,[{role:””}],array,如果没有需要填[],如果是跨db,语法为[{role:””,db:””}]
  • authenticationRestrictions: 可选,类似于可访问的白名单,包括IP和users,3.6支持
  • writeConcern:写回执信息 参数为: w(value:number、majority、tag)、j(bool)、wtimeout(number)
    - w:0 无回执,写数据后无任何回执操作,就算有错误也不会返回错误给客户算,要避免
    - w:1 回执,默认行为,写数据到内存后发送确认,但如果没有落地磁盘时候发送宕机也会丢数据
    - w:2/N/majority 等待数据复制到2/N/大多数个节点再回执
    - j:true journal 刷盘之后再回执,解决w:1问题,mongo会先写入journal日志再落地,但每次刷新到磁盘的间隔,如果宕机,也会丢数据
    - wtimeout : 等待时间毫秒。设置的话最少要大于1,0代表不开启这个选项

实现自定义用户权限

我们一般用用户对mongo进行的读写操作,使用的是系统自带的readWrite,让我们看看这个自带角色都有哪些action吧:除了读权限外,Write的actions包括convertToCapped、createCollection、dropCollection、createIndex、dropIndex、insert、remove、renameCollectionSameDB、update。我们可以看到,Write的权限非常大,可以删除文档、集合、索引,这在生产环境是非常危险的,因为权限过大,你无法控制高危操作的产生。下面我们开始进行权限回收,即定义一个自己的角色给用户,比如,我们只给用户开通insert、remove、update的写权限,读权限复用本库的read权限。

  1. 首先,我们登录自己的mongo数据库,进入需要收敛的数据库,我这边有一个用户,权限是readWrite;
football:PRIMARY> show users
{
	"_id" : "bayern.testone",
	"user" : "testone",
	"db" : "bayern",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "bayern"
		}
	]
}
  1. 现在创建自己的权限,我们保留"insert",“update”,"remove"这三个写操作,以及继承读角色,这样我们就生成了自己的readWrite,适用范围当然是用户所在的库;
football:PRIMARY> db.createRole({role:"MyreadWrite",privileges: [ {resource: { db: "bayern", collection: "" }, actions: ["insert","update","remove" ] }],roles:[ {role:"read", db:"bayern"} ]})
{
	"role" : "MyreadWrite",
	"privileges" : [
		{
			"resource" : {
				"db" : "bayern",
				"collection" : ""
			},
			"actions" : [
				"insert",
				"update",
				"remove"
			]
		}
	],
	"roles" : [
		{
			"role" : "read",
			"db" : "bayern"
		}
	]
}
  1. 现在我们开始替换权限;
football:PRIMARY> db.grantRolesToUser("testone",[{role:"MyreadWrite",db:"bayern"}])
football:PRIMARY> db.revokeRolesFromUser("testone",[{"role" : "readWrite","db" : "bayern"}])
football:PRIMARY> show users
{
	"_id" : "bayern.testone",
	"user" : "testone",
	"db" : "bayern",
	"roles" : [
		{
			"role" : "MyreadWrite",
			"db" : "bayern"
		}
	]
}
  1. 验证一下,写入是没问题滴,但是删除集合等操作已经不允许了;
football:PRIMARY> db.klose.insert({'desc':'success'})
WriteResult({ "nInserted" : 1 })
football:PRIMARY> db.klose.find()
{ "_id" : ObjectId("5bc212634b4c7f09ccb179be"), "desc" : "success" }
football:PRIMARY> db.klose.drop()
2018-10-13T23:43:07.569+0800 E QUERY    [thread1] Error: drop failed: {
	"ok" : 0,
	"errmsg" : "not authorized on bayern to execute command { drop: \"klose\" }",
	"code" : 13
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DBCollection.prototype.drop@src/mongo/shell/collection.js:739:1
@(shell):1:1
  1. 用pymongo验证了一下,当授权被替换掉后,程序中连接mongo的session会立刻生效,无需重启服务; 当然了,权限被收敛后,表和索引的操作,运维这边会多起来,所以就需要一个mongo的运维平台来支撑,这个正在酝酿中…

你可能感兴趣的:(MongoDB)