mongodb用户安全认证详解

作者:su377486

一..验证介绍

mongodb支持针对连接的用户验证,使用参数 auth打开验证功能:
    
[root@mongodb2 ~]# mongod -h |grep aut
  • 1
--keyFile arg private key for cluster authentication
  • 1
--noauth run without security
  • 1
authentication. Alternatives are
  • 1
--auth run with security
  • 1
--autoresync automatically resync if slave data is
  • 1
最好的策略是为每个人或者每个应用分配唯一的用户.
为用户创建或者使用内建的指定角色,然后将角色赋予给用户授权,遵循的原则是最小权限原则.mongodb不能直接将权限赋予给用户.
在打开auth之前需至少添加一个管理员用户,然后在添加其它的额外用户,否则mongodb将使用一个本地认证,以便让你可以创建一个管理员账户.
mongodb认证方式有多种,如password认证,kerberos认证,ldap认证等等,这里主要讲的是密码认证,也是用的最多的.

二.管理用户和角色

1.创建一个管理员用户

在开启验证之前必须创建一个管理员用户,管理员用户拥有 userAdminAnyDatabase角色.此角色拥有管理用户的权限,注意此角色并不是最大权限的角色.
我们使用 db.createUser()来创建用户,下面例子我们创建一个管理员用户root,密码root:
    
>use admin ?db.createUser( { user: "root", pwd: "root", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } )
Successfully added user: {
  • 1
"user" : "root",
  • 1
"roles" : [
  • 1
{
  • 1
"role" : "userAdminAnyDatabase",
  • 1
"db" : "admin"
  • 1
}
  • 1
]
  • 1
}
  • 1
mongos>
  • 1
使用root来登录mongodb:
     
[root@mongodb3 ~]# mongo --port 37017 -u root -p root --authenticationDatabase admin
  • 1
userAdminAnyDatabase角色拥有如下权限:
    
changeCustomData
  • 1
changePassword
  • 1
createRole
  • 1
createUser
  • 1
dropRole
  • 1
dropUser
  • 1
grantRole
  • 1
revokeRole
  • 1
viewRole
  • 1
viewUser
  • 1

2.创建一个超级管理员用户

一些角色提供了间接的或者直接的超级管理员权限.如果一个用户拥有下面三个角色那么可以称之为超级管理员权限
下列角色提供了在任何数据库中分配任何用户权限的能力,这就意味着他们可以分配给自己任何数据库任何权限:
1. dbOwner role, when scoped to the admin database
2. userAdmin role, when scoped to the admin database
3. userAdminAnyDatabase role
例如我们创建一个suq用户,拥有三个角色:
    
db.createUser(
  • 1
{
  • 1
user: "suq",
  • 1
pwd: "suq",
  • 1
roles: [
  • 1
{ role: "dbOwner", db: "admin" },
  • 1
{ role: "userAdmin", db: "admin" },
  • 1
{ role: "userAdminAnyDatabase", db: "admin" }
  • 1
]
  • 1
}
  • 1
)
  • 1

mongodb还直接提供了一个超级管理员角色root,例如我们创建一个admin用户为超级管理员:
    
use admin
  • 1
db.createUser(
  • 1
{
  • 1
user: "admin",
  • 1
pwd: "admin",
  • 1
roles: [ { role: "root",db:"admin" }]
  • 1
 
  • 1
}
  • 1
)
  • 1
当你使用admin登录mongodb的时候会有提示,不建议用超级管理员登录:
    
[root@mongodb3 ~]# mongo --port 37017 -u admin -p admin --authenticationDatabase admin
  • 1
MongoDB shell version: 3.2.6
  • 1
connecting to: 127.0.0.1:37017/test
  • 1
Server has startup warnings:
  • 1
2016-06-24T18:41:47.116+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
  • 1
2016-06-24T18:41:47.116+0800 I CONTROL [initandlisten]
  • 1
切换用户使用 db.auth()方法:
    
> db.auth("admin","admin")
  • 1

3.创建角色

角色用来授予给用户来控制用户使用mongodb的资源.mongdb提供了一套内置的角色,管理员可以直接使用这些角色来控制访问mongodb.然而如果这些内置的角色无法满足你的需求,你可以在单独的数据库里创建新的角色.
除了在admin数据库里创建的角色外,创建的的角色只能拥有此数据库内的权限.
在admin数据库内创建的角色,可以继承admin库,其他库,或者集群资源.也就是说在其它库里创建的角色只拥有此库的一些权限.
使用 db.createRole()来创建角色.
创建角色你必须有如下两个条件:
1.在数据库有createRole权限
2.你需要有授予指定权限的权限
内建角色userAdmin 和 userAdminAnyDatabase满足上述要求.因此一般以此管理员登录用户来执行.
createRole()的语法如下:
    
{
  • 1
role: "<name>",
  • 1
privileges: [
  • 1
{ resource: { <resource> }, actions: [ "<action>", ... ] },
  • 1
...
  • 1
],
  • 1
roles: [
  • 1
{ role: "<role>", db: "<database>" } | "<role>",
  • 1
...
  • 1
]
  • 1
}
  • 1
其中:
role是创建的role的名字.
resource是你想授权所对应的对象,例如 resource: { db: "users", collection: "usersCollection" }表示你想把users.userscollection的资源授予给此角色.这里是官网对resource的介绍: https://docs.mongodb.com/manual/reference/resource-document/#resource-document
actions是你想授予的动作,例如actions: [ "update", "insert", "remove" ],这里有官网对action的介绍: https://docs.mongodb.com/manual/reference/privilege-actions/#security-user-actions
roles是表示你想把某个角色授予给此角色.
下面一个实例:
    
use admin
  • 1
db.createRole(
  • 1
{
  • 1
role: "myClusterwideAdmin",
  • 1
privileges: [
  • 1
{ resource: { cluster: true }, actions: [ "addShard" ] },
  • 1
{ resource: { db: "config", collection: "" }, actions: [ "find", "update", "insert", "remove" ] },
  • 1
{ resource: { db: "users", collection: "usersCollection" }, actions: [ "update", "insert", "remove" ] },
  • 1
{ resource: { db: "", collection: "" }, actions: [ "find" ] }
  • 1
],
  • 1
roles: [
  • 1
{ role: "read", db: "admin" }
  • 1
]
  • 1
},
  • 1
{ w: "majority" , wtimeout: 5000 }
  • 1
)
  • 1

下面介绍几个创建角色的例子:
    创建一个角色管理当前操作
这个角色可以kill任何操作.以上面的root用户登录mongod:
    
[root@mongodb3 ~]# mongo --port 37017 -u root -p root --authenticationDatabase admin
  • 1
use admin
  • 1
db.createRole(
  • 1
{
  • 1
role: "manageOpRole",
  • 1
privileges:
  • 1
     [
  • 1
{ 
  • 1
        resource: { cluster: true }, 
  • 1
        actions: [ "killop", "inprog" ] 
  • 1
        },
  • 1
{ 
  • 1
        resource: { db: "", collection: "" }, 
  • 1
        actions: [ "killCursors" ] 
  • 1
        }
  • 1
],
  • 1
roles: []
  • 1
}
  • 1
)
  • 1
    创建一个角色可以运行mongostat
    
use admin
  • 1
db.createRole(
  • 1
{
  • 1
role: "mongostatRole",
  • 1
privileges: [
  • 1
{
  • 1
        resource: { cluster: true }, 
  • 1
        actions: [ "serverStatus" ] 
  • 1
        }
  • 1
],
  • 1
roles: []
  • 1
}
  • 1
)
  • 1

4.查看角色权限

使用 db.getRole()方法来获得角色的权限:
    
> db.getRole("mongostatRole")
  • 1
{
  • 1
"role" : "mongostatRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ]
  • 1
}
  • 1
查看详细的角色:
    
> db.getRole("mongostatRole",{showPrivileges: true})
  • 1
{
  • 1
"role" : "mongostatRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ],
  • 1
"privileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"serverStatus"
  • 1
]
  • 1
}
  • 1
],
  • 1
"inheritedPrivileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"serverStatus"
  • 1
]
  • 1
}
  • 1
]
  • 1
}
  • 1
还可以使用 db.getRoles()查看所有的非内建的角色:
    
> db.getRoles()
  • 1
[
  • 1
{
  • 1
"role" : "manageOpRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ]
  • 1
},
  • 1
{
  • 1
"role" : "mongostatRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ]
  • 1
}
  • 1
]
  • 1
     
> db.getRoles({showPrivileges: true})
  • 1
[
  • 1
{
  • 1
"role" : "manageOpRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ],
  • 1
"privileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"inprog",
  • 1
"killop"
  • 1
]
  • 1
},
  • 1
{
  • 1
"resource" : {
  • 1
"db" : "",
  • 1
"collection" : ""
  • 1
},
  • 1
"actions" : [
  • 1
"killCursors"
  • 1
]
  • 1
}
  • 1
],
  • 1
"inheritedPrivileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"inprog",
  • 1
"killop"
  • 1
]
  • 1
},
  • 1
{
  • 1
"resource" : {
  • 1
"db" : "",
  • 1
"collection" : ""
  • 1
},
  • 1
"actions" : [
  • 1
"killCursors"
  • 1
]
  • 1
}
  • 1
]
  • 1
},
  • 1
{
  • 1
"role" : "mongostatRole",
  • 1
"db" : "admin",
  • 1
"isBuiltin" : false,
  • 1
"roles" : [ ],
  • 1
"inheritedRoles" : [ ],
  • 1
"privileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"serverStatus"
  • 1
]
  • 1
}
  • 1
],
  • 1
"inheritedPrivileges" : [
  • 1
{
  • 1
"resource" : {
  • 1
"cluster" : true
  • 1
},
  • 1
"actions" : [
  • 1
"serverStatus"
  • 1
]
  • 1
}
  • 1
]
  • 1
}
  • 1
]
  • 1

5.查看用户角色

使用 db.getUser()方法来查看用户的所赋予的角色:
    
> db.getUser("suq")
  • 1
{
  • 1
"_id" : "admin.suq",
  • 1
"user" : "suq",
  • 1
"db" : "admin",
  • 1
"roles" : [
  • 1
{
  • 1
"role" : "dbOwner",
  • 1
"db" : "admin"
  • 1
},
  • 1
{
  • 1
"role" : "userAdmin",
  • 1
"db" : "admin"
  • 1
},
  • 1
{
  • 1
"role" : "userAdminAnyDatabase",
  • 1
"db" : "admin"
  • 1
}
  • 1
]
  • 1
}
  • 1

还可以使用db.getUsers()获取全部的用户信息:

     
> db.getUsers()
  • 1
[
  • 1
{
  • 1
"_id" : "admin.root",
  • 1
"user" : "root",
  • 1
"db" : "admin",
  • 1
"roles" : [
  • 1
{
  • 1
"role" : "userAdminAnyDatabase",
  • 1
"db" : "admin"
  • 1
}
  • 1
]
  • 1
},
  • 1
{
  • 1
"_id" : "admin.admin",
  • 1
"user" : "admin",
  • 1
"db" : "admin",
  • 1
"roles" : [
  • 1
{
  • 1
"role" : "root",
  • 1
"db" : "admin"
  • 1
}
  • 1
]
  • 1
},
  • 1
{
  • 1
"_id" : "admin.suq",
  • 1
"user" : "suq",
  • 1
"db" : "admin",
  • 1
"roles" : [
  • 1
{
  • 1
"role" : "dbOwner",
  • 1
"db" : "admin"
  • 1
},
  • 1
{
  • 1
"role" : "userAdminAnyDatabase",
  • 1
"db" : "admin"
  • 1
}
  • 1
]
  • 1
}
  • 1
]
  • 1


6.授予/收回角色权限

使用db.revokePrivilegesFromRole() db.grantPrivilegesToRole() 方法收回和赋予角色权限
     
db.revokePrivilegesFromRole(
  • 1
"manageOpRole",
  • 1
[
  • 1
{ resource: {"cluster" : true}, actions: ["inprog","killop"] }
  • 1
]
  • 1
)
  • 1
      
db.grantPrivilegesToRole(
  • 1
"manageOpRole",
  • 1
[
  • 1
{
  • 1
resource: {"cluster" : true},
  • 1
actions: ["inprog","killop"]
  • 1
}
  • 1
]
  • 1
)
  • 1

7.授予/收回用户角色

使用 db.revokeRolesFromUser()来收回用户所赋予的角色
    
db.revokeRolesFromUser( "suq", [ { role: "userAdmin", db: "admin" } ] )
使用 db.grantRolesToUser()来给用户授予角色:
    
db.grantRolesToUser(
  • 1
"reportsUser",
  • 1
[
  • 1
{ role: "userAdmin", db: "admin" }
  • 1
]
  • 1
)
  • 1

8.修改用户密码

使用 db.changeUserPassword()方法来给用户修改密码:
    
> db.changeUserPassword("suq", "111111")
  • 1

三.内置角色和内置权限

内置的角色,查看官方文档:

四.用户和角色方法

详细参见官方文档:

Role Management

Name Description
db.createRole() Creates a role and specifies its privileges.
db.updateRole() Updates a user-defined role.
db.dropRole() Deletes a user-defined role.
db.dropAllRoles() Deletes all user-defined roles associated with a database.
db.grantPrivilegesToRole() Assigns privileges to a user-defined role.
db.revokePrivilegesFromRole() Removes the specified privileges from a user-defined role.
db.grantRolesToRole() Specifies roles from which a user-defined role inherits privileges.
db.revokeRolesFromRole() Removes inherited roles from a role.
db.getRole() Returns information for the specified role.
db.getRoles() Returns information for all the user-defined roles in a database.

User Management

Name Description
db.auth() Authenticates a user to a database.
db.createUser() Creates a new user.
db.updateUser() Updates user data.
db.changeUserPassword() Changes an existing user’s password.
db.removeUser() Deprecated. Removes a user from a database.
db.dropAllUsers() Deletes all users associated with a database.
db.dropUser() Removes a single user.
db.grantRolesToUser() Grants a role and its privileges to a user.
db.revokeRolesFromUser() Removes a role from a user.
db.getUser() Returns information about the specified user.
db.getUsers() Returns information about all users associated with a database.

五.用户角色权限集合

mongodb的用户和角色信息存放在admin数据库下的system.users和system.roles集合中.
mongodb建议修改用户和角色使用上面的用户和角色的方法,不要直接修改集合的数据.
system.roles集合数据大致如下:
    
{
  • 1
_id: <system-defined id>,
  • 1
role: "<role name>",
  • 1
db: "<database>",
  • 1
privileges:
  • 1
[
  • 1
{
  • 1
resource: { <resource> },
  • 1
actions: [ "<action>", ... ]
  • 1
},
  • 1
...
  • 1
],
  • 1
roles:
  • 1
[
  • 1
{ role: "<role name>", db: "<database>" },
  • 1
...
  • 1
]
  • 1
}
  • 1
system.users集合数据大致如下:
    
{
  • 1
_id: <system defined id>,
  • 1
user: "<name>",
  • 1
db: "<database>",
  • 1
credentials: { <authentication credentials> },
  • 1
roles: [
  • 1
{ role: "<role name>", db: "<database>" },
  • 1
...
  • 1
],
  • 1
customData: <custom information>
  • 1
}
  • 1
具体的说明几乎和上面的一致,就不赘述了,有兴趣的话可以查看官方文档:
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐