微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MongoDB用户验证和权限管理

官方参考页面:

https://docs.mongodb.com/v3.6/tutorial/enable-authentication/

https://docs.mongodb.com/v3.6/tutorial/enforce-keyfile-access-control-in-existing-replica-set/

前言:

前些年很多用户对mongodb的安全意识是很淡漠的,也因此在前几年出现了一些很严重的针对mongodb的攻击。

本文以mongodb3.6为例,介绍mongodb目前的用户验证机制,当然用户验证只是mongodb安全体系的一部分,更加全面的安全内容参考:https://docs.mongodb.com/v3.6/security/

虽然mongodb提供了一系列的加强安全的措施,但实际上经常会用到的也就是用户验证集群成员间的keyfile验证了,关于集群节点间的keyfile验证参考上述的第二个官方链接即可,这种keyfile只是为了防止陌生节点加入集群,是mongo实例级别的。

本文只介绍最核心的用户验证,这种用户验证的粒度是库级别的。

一、如何创建用户?

安装MongoDB后auth认证默认是关闭的,此时admin库是不可见的(旧版本不可见,新版本里只是admin下的用户相关的system.users不可见),现创建一个超级帐号:

use admin
db.createUser({user: "root",pwd: "root",roles: [ { role: "root", db: "admin" } ]})
db.changeUserPassword('root','rootNew');  
//更改密码语句如上
db.dropUser("<username>")
//删除用户命令如上,虽然所有库的用户信息全存在admin的system.users中,删用户时还是要use <库名>才能删除。

创建用户时需要牢记的几点:

  • 创建用户必须指定库名,即便是超级用户的创建也是如此(即用户是和库绑定的),如果你创建root用户时是在业务库里,那你以后登录root也只能指定业务库的库名了。
  • 不同的库下可以存在相同的用户名,即admin.root用户和test.admin用户是可以同时存在的。
  • 登陆mongo shell时如果不指定库名,默认登入的test库(只在3.6验证过,其他版本自行验证),你需要use db_name后才能进行db.auth()
  • 内置的roles都是属于admin库的,因此在创建用户时roles后边的db都是admin。
  • 一般来说创建一个root角色的超级用户root即可,创建一些普通权限的用户做日常操作。
  • 虽然用户和库是绑定的,但是用户的权限却是可以跨库的,即只要权限正确某个库下的某个用户也可以操作任意其他库。
示例:一次创建多个用户 和 创建包含多个角色的用户:
use test
db.createUser(
  {
    user: "myTester",
    pwd: "xyz123",
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "reporting" } ]
  }
)
use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

二、什么是角色(roles)?

https://docs.mongodb.com/manual/reference/built-in-roles/index.html

roles即一系列权限的集合,系统内置了一系列的built-in roles以便可以方便的为用户授权,一般来说使用这些built-in roles创建用户就可以了,除非你需要更细粒度的指定权限(那你可能需要下点功夫看官网文档)。

Built-In Roles简略介绍(详细介绍参考以上官方链接):
Database User Roles:
	read
    	提供本库下所有非系统collection的读权限,以及少数几个系统collection的读权限,例如system.indexes, system.js, and system.namespaces
    readWrite
    	提供本库下所有非系统collection的读写权限,以及系统collection system.js的读写权限。
Database Administration Roles:
	dbAdmin
    	提供一些库管理的权限,诸如索引创建,增删集合,删库等等,并没有对所有集合的读权限,因此其实很少会用到。
    userAdmin
    	提供在本库下创建用户、角色,删除用户、角色,修改密码等一系列用户相关的权限。
    dbOwner
    	库拥有者权限,即readWrite、dbAdmin、userAdmin角色的合体。
Cluster Administration Roles:
	clusterAdmin
    	集群管理权限,clusterManager、clusterMonitor、hostManager角色的合体,此外再加上dropDatabase权限。
    clusterManager
    	集群管理者权限,提供诸如添加shard,删除shard,修改副本集配置等权限。
    clusterMonitor
    	集群监控权限,顾名思义拥有查看一系列集群状态的权限。
    hostManager
    	参考官网链接的解释,很少使用。
Backup and Restoration Roles:
	backup
    	即进行数据备份的权限,实例级别的角色。
    restore
    	即进行数据还原的权限,实例级别的角色,还包含很多与dbOwner重合的权限,参见官网中的相关解释。
All-Database Roles:
	readAnyDatabase
    	提供针对除了local和config库外所有其他库的读权限。
    readWriteAnyDatabase
    	提供针对除了local和config库外所有其他库的读写权限。
    userAdminAnyDatabase
    	同userAdmin角色,只不过范围扩大到了所有库。
    dbAdminAnyDatabase
    	同dbAdmin角色,只不过范围扩大到了所有库。
Superuser Roles:
	root
    	即超级用户的权限,拥有此权限你可以做你想做的任何事,可以将此角色理解为dbOwnerAnyDatabase。
Internal Role:
	__system
    	系统内置角色,不能给用户赋予,不多解释。

一般来说应用使用的用户只需要readWrite角色即可,DBA可使用root账户和clusterAdmin账户进行诸如集群配置,备份恢复等操作。

如何查看用户的权限:

use admin
db.system.users.find()  //所有库的用户全部存在admin的system.users中

三、如何开启验证登陆:

之前说了如何创建用户和指定权限,那么如何使用户登录验证生效呢?

在配置文件添加auth=true参数重启之后,使用mongo登陆:

use db_name  //用户必须切换到其相应的库登陆。3.6版本中默认登陆的一般是test库,所以要注意使用use dbname切换到用户对应的库
db.auth('xxx','xxx')  //登陆相应的库之后就可以操作数据啦
--或者直接在命令行中登陆:
mongo db_name -u username -p password

四、关于Localhost Exception

https://docs.mongodb.com/manual/core/security-users/#localhost-exception

mongodb配置文件中有个配置项enableLocalhostAuthBypass,其默认值为1(true)。

这个参数=1的含义是:

    如果你设置了auth=true,但是还未创建user或者不知道原来的用户密码想新建一个,那么此参数允许你在本地登陆时创建用户,然后使用此新建的用户验证登录。

    相应的如果此参数为0,那么如果你未创建用户或者忘记了账号密码,那么即便在本地登陆mongo shell,也不允许你新建用户。

因此官网建议将此参数设置为0或false,从而防止有人可以在服务器本地新建超级权限的用户。

But!!!都特么能登陆服务器本地了,你设置此参数为false有软用啊,我都可以直接改配置文件重启服务啦,因此这个参数其实毫无软用(可能对那些可以登陆服务器但是并无修改配置文件权限和启停mongo权限的用户有点用吧)。

保险起见这里还是贴下enableLocalhostAuthBypass参数的设置方法:

在配置文件里添加setParameter=enableLocalhostAuthBypass=1,然后重启(这是非YAML的设置方式,YAML的设置方式官网示例很完善了动手去查下就知道)。

  五、关于集群用户

https://docs.mongodb.com/v3.6/core/security-users/#sharded-cluster-users

mongodb还针对sharding集群提供了shard local user,普通的用户称作shard cluster user,集群用户可以通过mongos登陆并操作整个集群的数据,但是shard local user只能操作特定的shard,这对一些仅能使用集群用户执行的操作来说就很好了,例如 cleanupOrphaned, compact, rs.reconfig()等操作。

在mongos上创建的用户属于shard cluster user,在shard本地节点创建的用户就是shard local user了。在mongo2.6之后集群用户是存储在config server上的。

更多的关于集群用户的相关知识参见上述官网链接,这里不再详述。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐