MongoDB账号管理及实践
此文已由作者温正湖授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
目前蜂巢(云计算基础服务)MongoDB上已经有数十个实例,其中不少是企业用户或公司内部产品用户的。用户多了,那就会反馈一些问题。其中一个就是MongoDB实例访问账号,虽能够提供创建和删除集合、索引,创建数据库等用户所需的权限,但无法删除数据库,这个问题虽然不严重,但多少会影响用户体验。那么这是为什么呢?本文以此作为入口来谈谈MongoDB的账号管理。
MongoDB作为一个成熟的数据库,像MySQL一样,也提供账号管理,但又跟MySQL不大一样,MongoDB使用基于角色的访问权限控制(Role-Based Access Control,RBAC),包括账号(Users,直译为用户,但似乎账号更好理解)、角色(Roles)和权限(Privileges)三层关系。权限指的是允许对某种资源进行的某些操作。这里所说的资源,包括数据库、集合和集群等。在进行MongoDB权限管理操作时,资源使用一个文档来表示,比如数据库mydb下的集合mycoll作为一种资源表示为{db: "mydb", collection: "mycoll"}。{db: "mydb", collection: ""}表示数据库mydb下的所有集合。对应地,{db: "", collection: "mycoll"}就是所有数据库下的mycoll集合,集群资源表示为{cluster: true},如果要将所有数据库和集群作为一种资源那么可以表示为{anyResource: true}。所说的操作包括对集合的CRUD,查看数据库下的集合列表,查看复制集或分片集群当前状态等。根据操作类型,又可以分为:读写操作,数据库管理操作,集群部署操作,复制集操作,分片集群操作,系统管理操作,诊断操作,内部操作等8大类。
MongoDB对外提供的是账号,作为访问MongoDB认证单位。内部,一个账号可以由0到多个角色组成,角色分为内建角色(Built-In Roles)和自定义角色(User-Defined Roles)。为了方便使用,MongoDB提供了多种内建角色,分为数据库用户,数据库管理员,集群管理员,备份和恢复角色,跨数据库角色,超级用户,内部用户等7大类,每个大类下面有可以分为不同权限的角色,比如数据库用户大类可细分为读read和读写readWrite两种角色,而每个角色拥有一定的权限,比如readWrite角色具有创建/删除集合、创建删除索引和集合CRUD等16种权限,跨数据库角色表示该角色不仅对某个数据库有指定的操作权限,还对实例中其他所有(用户创建的)的数据库都具备同样的权限,比如readWriteAnyDatabase,具备对所有数据库有readWrite权限。这里有个特例,就是给用户授权角色时,如果授权时指定的数据库是admin,则即使仅指定readWrite,也同样具备readWriteAnyDatabase角色,也就是说对admin具有readWrite角色,那么对其他数据库也具有,天然具有AnyDatabase光辉。
蜂巢(云计算基础服务)MongoDB提供了MongoDB复制集实例,用户可以创建readWriteAnyDatabase权限的账号来访问MongoDB,为什么要AnyDatabase呢?因为我们还未提供MongoDB的数据库和账号管理功能(接管用户所有的数据库/集合、用户创建和权限管理操作),无法限制用户创建数据库,所以也就无法为特定某个数据库授予readWrite权限。readWriteAnyDatabase权限具备了复制集场景下用户所需的绝大部分权限,包括集合、索引的创建和删除,数据库/集合等统计信息。就像文章刚开始的描述一样,其不具备删除数据库(dropDatabase)这个权限,虽然有点坑,但还不是大问题,只需在后续提供MongoDB的数据库和账号管理功能中,将dropDatabase权限纳入管理即可。但在分片集群场景下,readWriteAnyDatabase所具有的的权限已经根本无法满足用户的正常操作,比如对数据库启用分片功能(enableSharding),人工进行分片的chunk拆分(splitChunk),在我们没有数据库和账号管理功能前,这些操作都需要用户端来执行,而readWriteAnyDatabase无法满足。那么是不是有其他内建角色满足需求呢,查阅官方文档发现集群管理员下的clusterManager角色提供了我们所需的权限,但其还提供了诸如在分片集群中添加和删除分片服务器,在复制集中进行复制集重配置等重型权限,如果给用户这些权限将是非常危险的。所以,在蜂巢分片集群实例中,无法通过为用户提供拥有多个内建角色(如readWriteAnyDatabase、clusterManager两个)的账号来满足用户正常使用的需求。这个时候,自定义角色就派送用场了,在创建自定义角色时,既可以指定对资源的操作权限,还可以选择继承另一个角色所拥有的权限,比如,提供给用户的新账号继承了readWriteAnyDatabase角色的所有权限,还额外添加了dropDatabase、enableSharding和splitChunk等权限,这样一来就顺利解决了面临的问题。
关说不练假把式,结合以上的描述,演示如何为MongoDB进行账号管理操作。
1、首先在mongod配置文件中增加权限相关设置 security: {authorization: enabled, keyFile: /home/mongo/keyfile}。其中authorization表示是否启用访问权限认证,keyFile指定了MongoDB复制集或分片集群内部各组件相互间通信的认证文件;MongoDB提供了本地例外机制,避免用户在启用认证前未设置账号导致无法访问MongoDB实例的尴尬;
2、创建用户所需的数据库账号,如下:
mongos> use admin
mongos> db.createUser(
{
user: "myuser",
pwd: "xxxxx",
roles: [ { role: "readWrite", db: "admin" } ]
}
)
指定了认证数据库为admin,角色采用内建的readWrite,由于指定的数据库是admin,那么等同于创建了readWriteAnyDatabase角色的账号。用该账号登陆:
use admin
db.auth("myuser","wzh123")
3、但该账号无法执行如下这些操作:
mongos> use mydb
mongos> db.dropDatabase()
{
"ok" : 0,
"errmsg" : "not authorized on shardtest to execute command { dropDatabase: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
}
mongos> sh.enableSharding("wzhshard")
{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { enableSharding: \"wzhshard\" }",
"code" : 13,
"codeName" : "Unauthorized"
}
4、所以,只能通过创建自定义角色来满足需求,先切换到root账号:
use admin
db.auth("root","wzh123") // root为已创建的具备超级用户角色的管理账号。
创建自定义角色:
db.createRole({
role: "wzhRole",
privileges: [{ resource: { db: "", collection: "" }, actions: ["enableSharding","dropDatabase" ] }],
roles: ["readWriteAnyDatabase"]
})
privileges字段指定了该角色具有的对resource字段所述资源具有actions字段所述的操作权限enableSharding和dropDatabase,同时通过roles字段继承了readWriteAnyDatabase的所有权限。
5、进一步操作myuser账号,先去掉其readWrite角色,操作如下:
db.revokeRolesFromUser(
"myuser",
[
{ role: "readWrite", db: "admin" }
]
)
确认权限已收回:
mongos> db.getUser("myuser")
{
"_id" : "admin.myuser",
"user" : "myuser",
"db" : "admin",
"roles" : [ ]
}
6、为myuser增加wzhRole角色:
db.grantRolesToUser(
"myuser",
[
{ role: "wzhRole", db: "admin" }
]
)
确认权限已经赋予:
db.getUser("myuser")
{
"_id" : "admin.myuser",
"user" : "myuser",
"db" : "admin",
"roles" : [
{
"role" : "wzhRole",
"db" : "admin"
}
]
}
7、再使用myuser登陆
use admin
db.auth("myuser","wzh123")
8、执行操作:
mongos> sh.enableSharding("wzhshard")
{ "ok" : 1 }
mongos> sh.shardCollection("wzhshard.table1",{mykey:1})
{ "collectionsharded" : "wzhshard.table1", "ok" : 1 }
mongos> use wzhshard
switched to db wzhshard
mongos> db.dropDatabase()
{ "dropped" : "wzhshard", "ok" : 1 }
一切看起来那么美好!
MongoDB在权限管理中引入了角色这一中间层,一般情况下,直接基于内建角色来创建账号即可,有特殊需求的话,可以创建自定义角色来满足需求,这样一来就无需暴露繁多的具体权限。对于新司机,更容易上手。但不足之处在于MongoDB数据库并未像MySQL一样未提供IP过滤功能(未提供Host字段用来设置账号所适用的主机IP列表)。
最后,网易数据库团队正在热火朝天地调研和开发MongoDB分片集群功能,计划上半年在蜂巢(云计算基础服务)上提供MongoDB分片集群能力,届时将带给大家更加强大的文档数据库能力。
网易云数据库RDS是一种稳定可靠、可弹性伸缩的在线关系型数据库服务,当前支持MySQL引擎,提供基础版,高可用版,金融版针对不同业务场景的高可用解决方案,同时提供多重安全防护措施,性能监控体系,专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。
参考资料:
1、https://docs.mongodb.com/manual/reference/built-in-roles
2、https://docs.mongodb.com/manual/reference/privilege-actions/
3、https://docs.mongodb.com/manual/reference/resource-document/
4、https://docs.mongodb.com/manual/core/authorization/
5、https://docs.mongodb.com/manual/core/security-user-defined-roles/
6、https://docs.mongodb.com/manual/tutorial/manage-users-and-roles/
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 Android优化之内存优化倒计时篇
【推荐】 混合APP开发-hybrid 升级流程
MongoDB账号管理及实践的更多相关文章
- MongoDB基本管理命令
MongoDB是一个NoSQL数据库系统:一个数据库可以包含多个集合(Collection),每个集合对应于关系数据库中的表:而每个集合中 可以存储一组由列标识的记录,列是可以自由定义的,非常灵活,由 ...
- MongoDB——权限管理
MongoDB--权限管理 MongoDB默认是没有权限验证的,但生产环境中,没有权限控制是很不安全的. 我们先不详谈太多概念,直接动手创建两个典型的账号: 超级管理员,类似sql server的sa ...
- HUST高级软件工程--测试管理工具实践--Day4
测试管理工具实践--Day4 今天完成任务情况: 小靳 今天,主要在前两天的基础上继续学习挖掘jira相关内容: 学会了如何创建项目,并且创建了issue 学会了创建一般账号,并且可以将任务分发给一般 ...
- HUST高级软件工程--测试管理工具实践--Day3
测试管理工具实践--Day3 今天完成任务情况: 小靳 今天,大家参加考试,时间比较紧促.庆幸,自己的队伍比较给力,大家都没有拖后腿,深夜还在为自己的任务拼搏,很是激励人心 我今天的工作就是 学会了注 ...
- HUST高级软件工程--测试管理工具实践--Day1
测试管理工具实践--Day1 今天完成任务情况: 课前组好队伍,建好微信群. 课上通过老师的介绍,初步了解各种测试工具的使用情况. 课后选取了组长,在微信群经过"广泛而激烈"的讨论 ...
- SNF快速开发平台2019-用户安全控制-权限管理模型实践-权限都在这里
1.1 是否保存密码 勾选记住密码后,再次开启程序用户密码不需要再次输入,直接显示在密码输入框内,方便快捷. 图 4.1‑1 记住密码的登录页面框 1.2 是否自动登录 勾选自动登录后,再 ...
- MySQL基础知识:启动管理和账号管理
整理.记录常用的MySQL基础知识:时间久了,很多就忘记了. 操作系统环境为MacOS Catalina, MySQL版本为: 8.0.13 MySQL Community Server - GPL. ...
- Android 6.0 权限管理最佳实践
博客: Android 6.0 运行时权限管理最佳实践 github: https://github.com/yanzhenjie/AndPermission
- NoSQL学习二:MongoDB基本管理命令
MongoDB命令学习 一.MongoDB命令帮助 在安装MongoDB后,启动服务器进程(mongod),可以通过在客户端命令mongo实现对MongoDB的管理和监控: 这是MongoDB最上层 ...
随机推荐
- TCP/IP协议 socket
TCP/IP四层协议 TCP/IP概念 tcp/ip协议是主机接入互联网以及接入互联网的两台主机通信的标准. 数据帧概念 数据帧 |-- 包头 | |--源地址 | |--目标地址 | |--数据类型 ...
- x264改变输出分辨率的算法<转>
x264改变输出分辨率的算法 在某些应用场景下,x264的输入视频分辨率与接收端输出的视频分辨率不同.例如编码端摄像头采集到的YUV数据为1280x720,而接收端视频显示窗口为640x480.对于这 ...
- 归纳整理Linux下C语言常用的库函数----字符串转换、字符测试、及内存控制
在没有IDE的时候,记住一些常用的库函数的函数名.参数.基本用法及注意事项是很有必要的. 参照Linux_C_HS.chm的目录,我大致将常用的函数分为一下几类: 1. 内存及字符串控制及操作 2. ...
- 读取和反序列化Hadoop二进制文件
目录 问题描述 反序列化代码 问题描述 Hadoop在运行MR时,经常要将一些中间结果存到本地,为了节省存储空间,Hadoop采用序列化机制(Hadoop的序列化机制和Java的有所不同)将数据保存为 ...
- Win7删除远程连接历史记录
打开注册表,找到 HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default 删除右侧的 MRUn(n是索引号) 项 即可.
- Ant+jmeter+jenkins搭建测试的持续集成
前提: Ant+jmeter 已经搭建完成并成功运行(参看ant+jmeter自动化性能测试) Jenkins在本地已经安装可运行(参看上一篇) 1.下载Jenkins安装 2.浏览器输入地址http ...
- QEMU 代码分析:BIOS 的加载过程
http://www.ibm.com/developerworks/cn/linux/1410_qiaoly_qemubios/ QEMU 中使用 BIOS 简介 BIOS 提供主板或者显卡的固件信息 ...
- 6-查看centos中的用户和用户组
转载自:http://www.cnblogs.com/ermao0423/p/9510636.html 查看centos中的用户和用户组 1.用户列表文件:/etc/passwd/ 2.用户组列表文件 ...
- windows查看内存频率
命令行查看: wmic memorychip 任务管理器查看: 任务管理器-性能-内存-速度
- TOGAF架构培训材料学习总结
作于一个架构师尤其是企业架构师来说,丰富的理论知识可以帮助他在架构规划及管理过程中站在更高的角度去看待问题,历史发展原因有很多已成体系的架构理论,TOGAF是近年来比较接地气的,受到了政府和银 ...