Mongodb作为时下最为热门的数据库,那么其安全验证也是必不可少的,否则一个没有验证的数据库暴露出去,任何人可随意操作,这将是非常危险的。我们可以通过使用为MongoDB创建用户的方式来降低风险

1、MongoDB中的常用权限

read

允许用户读取指定数据库

readWrite

允许用户读写指定数据库

dbAdmin

允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin

允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户

clusterAdmin

只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限

readAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限

root

只在admin数据库中可用。超级账号,超级权限

2、mongodb用户使用

2.1、创建db管理员用户

mongodb 设置root 用户 mongodb 用户权限管理_数据库

2.1.1、切换到admin库

Welcome to Alibaba Cloud Elastic Compute Service !

#进入到mongodb的bin目录,bin目录里是可执行文件
[root@iZ2ze5v2vdwv6veyksylhxZ ~]# cd /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/bin/

#查看bin目录中可执行的命令
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ll
total 282152
-rwxr-xr-x 1 root root 10100811 Oct 16  2019 bsondump
-rwxr-xr-x 1 root root     7694 Oct 16  2019 install_compass
-rwxr-xr-x 1 root root 47534944 Oct 16  2019 mongo
-rwxr-xr-x 1 root root 71584856 Oct 16  2019 mongod
-rwxr-xr-x 1 root root 14765905 Oct 16  2019 mongodump
-rwxr-xr-x 1 root root 14511931 Oct 16  2019 mongoexport
-rwxr-xr-x 1 root root 14473296 Oct 16  2019 mongofiles
-rwxr-xr-x 1 root root 14690724 Oct 16  2019 mongoimport
-rwxr-xr-x 1 root root 18154584 Oct 16  2019 mongoreplay
-rwxr-xr-x 1 root root 15088133 Oct 16  2019 mongorestore
-rwxr-xr-x 1 root root 39806704 Oct 16  2019 mongos
-rwxr-xr-x 1 root root 14258080 Oct 16  2019 mongostat
-rwxr-xr-x 1 root root 13918118 Oct 16  2019 mongotop

#用配置文件启动mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 2634
child process started successfully, parent exiting

#启动mongodb客户端连接服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

#mongodb的客户端和服务器连接成功
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("58f0e762-1195-480e-a6ba-26ecbea8b4e7") }
MongoDB server version: 4.2.1
...
...

#切换数据库为 admin管理数据库
> use admin;
switched to db admin
>

2.1.2、查看admin中的用户

mongodb 设置root 用户 mongodb 用户权限管理_linux_02

2.1.3、db.createUser函数

db.createUser({ 
    user: "<name>",
    pwd: "<cleartext password>",
    customData: { <any information> },
    roles: [
        { role: "<role>", db: "<database>" } | "<role>",
        ...
    ]
});

mongodb 设置root 用户 mongodb 用户权限管理_linux_03

1)user:新建用户名
2)pwd:新建用户密码
3)customData:存放一些用户相关的自定义数据,该属性也可忽略
4)roles:数组类型,配置用户的权限
示例:db.createUser({user:‘bjsxt’,pwd:‘bjsxt’,roles:[{role:‘root’,db:‘admin’}])

2.1.4、创建管理员用户

mongodb 设置root 用户 mongodb 用户权限管理_linux_04


此命令创建管理员用户,用户名 pipi,密码 love,权限是 userAdminAnyDatabase

db.createUser({user:"pipi",pwd:"love",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})

Successfully added user: {
	"user" : "pipi",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		}
	]
}
>

创建成功后会看到如下提示

mongodb 设置root 用户 mongodb 用户权限管理_mongodb 设置root 用户_05


重启mongodb后创建的用户才可以生效

2.1.5、重启mongodb

mongodb 设置root 用户 mongodb 用户权限管理_mongodb 设置root 用户_06

# 创建管理员用户
> db.createUser({user:"pipi",pwd:"love",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
Successfully added user: {
	"user" : "pipi",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		}
	]
}

# mongodb关闭
> db.shutdownServer()
2021-09-20T09:07:24.532+0800 I  NETWORK  [js] DBClientConnection failed to receive message from 127.0.0.1:27017 - HostUnreachable: Connection closed by peer
server should be down...
2021-09-20T09:07:24.542+0800 I  NETWORK  [js] trying reconnect to 127.0.0.1:27017 failed
2021-09-20T09:07:24.542+0800 I  NETWORK  [js] reconnect 127.0.0.1:27017 failed failed 
> 

# ctrl+c 退出mongodb
> ^C
bye
2021-09-20T09:24:29.630+0800 I  NETWORK  [js] trying reconnect to 127.0.0.1:27017 failed
2021-09-20T09:24:29.630+0800 I  NETWORK  [js] reconnect 127.0.0.1:27017 failed failed 
2021-09-20T09:24:29.630+0800 I  QUERY    [js] Failed to end session { id: UUID("58f0e762-1195-480e-a6ba-26ecbea8b4e7") } due to SocketException: socket exception [CONNECT_ERROR] server [couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused]
[root@iZ2ze5v2vdwv6veyksylhxZ bin]#

重启mongodb服务器,再次查询创建的用户

# 查看bin目录所在路径
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# pwd
/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/bin

# 启动mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 30281
child process started successfully, parent exiting

#启动mongodb客户端,连接mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("cf19814d-1cc1-42c5-bc46-971e6ec0facc") }
MongoDB server version: 4.2.1
...
...

# 切换到admin数据库
> use admin;
switched to db admin

#数据库中查找出新创建的用户数据
> db.system.users.find()
{ "_id" : "admin.pipi", "userId" : UUID("3c779c02-d43e-48a7-aa87-a3204c9ba2ef"), "user" : "pipi", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "3B3ofb+tjOpnmahtjCF4+A==", "storedKey" : "d89PTeKH1PRMvGS3ECk0GcxQMp0=", "serverKey" : "PfocTc92mzPS/U3MFTV4gGsmTaM=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "teiJUL/HJ+ZsfH1kvoylIMZYLFo2B6mwT+zIeA==", "storedKey" : "ehpKopyTeHg8y8ntm0d0wmIdjf2JdSQYUeScvJf4NSs=", "serverKey" : "M9e57gCxHnfaE1xvxFLu1g7RrF13+ZTsVE5zcVw6PWU=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
>

2.1.6、使用权限方式启动mongodb

mongodb 设置root 用户 mongodb 用户权限管理_mongodb_07

# 进入目录 /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc
[root@iZ2ze5v2vdwv6veyksylhxZ mongodb-linux-x86_64-rhel70-4.2.1]# cd etc/

# etc目录里有mongodb.conf文件
[root@iZ2ze5v2vdwv6veyksylhxZ etc]# ls
mongodb.conf

# 编辑mongodb.conf文件,添加auth=true
[root@iZ2ze5v2vdwv6veyksylhxZ etc]# vim mongodb.conf 

# 修改mongodb.log,添加auth=true
dbpath=/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/data/db
logpath=/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/log/mongodb.log
port=27017
bind_ip=0.0.0.0
fork=true    
auth=true

# 查看目录路径
[root@iZ2ze5v2vdwv6veyksylhxZ etc]# pwd
/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc
[root@iZ2ze5v2vdwv6veyksylhxZ etc]#

2.1.7、用户认证

认证函数:db.auth(“用户名”,“密码”)
如果结果返回1,则表示认证成功,返回0则表示认证失败,登录成功后可查询用户

# 目录 /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf
# 启动mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 30196
child process started successfully, parent exiting

# 启动mongodb客户端,连接mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("fb544e88-95c2-4df9-be64-dd83d3ab2e3c") }
MongoDB server version: 4.2.1

# mongodb客户端成功连接mongodb服务器后,切换为admin数据库
> use admin
switched to db admin

# 查询已经创建好的用户信息,因为设置了权限拦截auth=true,所以不进行用户认证就无法查询数据
> db.system.users.find()
Error: error: {
	"ok" : 0,
	"errmsg" : "command find requires authentication",
	"code" : 13,
	"codeName" : "Unauthorized"
}

# 用户认证,成功返回1
> db.auth("pipi","love")
1

# 用户认证后,再次查询用户数据,就可以查出结果了
> db.system.users.find()
{ "_id" : "admin.pipi", "userId" : UUID("3c779c02-d43e-48a7-aa87-a3204c9ba2ef"), "user" : "pipi", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "3B3ofb+tjOpnmahtjCF4+A==", "storedKey" : "d89PTeKH1PRMvGS3ECk0GcxQMp0=", "serverKey" : "PfocTc92mzPS/U3MFTV4gGsmTaM=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "teiJUL/HJ+ZsfH1kvoylIMZYLFo2B6mwT+zIeA==", "storedKey" : "ehpKopyTeHg8y8ntm0d0wmIdjf2JdSQYUeScvJf4NSs=", "serverKey" : "M9e57gCxHnfaE1xvxFLu1g7RrF13+ZTsVE5zcVw6PWU=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
>

2.2、创建普通用户

普通用户由管理员创建,通常需要指定操作某个数据库

2.2.1、需求

创建一个 commonUser 数据库,给这个数据库添加一个用户,用户名为 dan,密码为 love,并授予该用户对 pidan 数据库进行读写操作的权限

2.2.2、使用管理员用户登录

普通用户需要由管理员创建并授权,所以我们首先做的就是用管理员账户登录数据库

mongodb 设置root 用户 mongodb 用户权限管理_mongodb 设置root 用户_08

2.2.3、创建普通用户名为commonUser的数据库

use命令切换数据库时,如果该数据库不存在,那么则会创建该数据库

mongodb 设置root 用户 mongodb 用户权限管理_数据库_09

2.2.4、管理员创建普通用户

# 启动mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 27015
child process started successfully, parent exiting

#启动mongodb客户端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("94aaf2c2-4b53-4879-bd7e-35d687409585") }
MongoDB server version: 4.2.1

#切换为admin数据库
> use admin
switched to db admin

#查询数据库信息
> db.system.users.find()
Error: error: {
	"ok" : 0,
	"errmsg" : "command find requires authentication",
	"code" : 13,
	"codeName" : "Unauthorized"
}

# 用户认证 是管理员
> db.auth("pipi","love")
1

#管理员再次查询数据库
> db.system.users.find()
{ "_id" : "admin.pipi", "userId" : UUID("3c779c02-d43e-48a7-aa87-a3204c9ba2ef"), "user" : "pipi", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "3B3ofb+tjOpnmahtjCF4+A==", "storedKey" : "d89PTeKH1PRMvGS3ECk0GcxQMp0=", "serverKey" : "PfocTc92mzPS/U3MFTV4gGsmTaM=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "teiJUL/HJ+ZsfH1kvoylIMZYLFo2B6mwT+zIeA==", "storedKey" : "ehpKopyTeHg8y8ntm0d0wmIdjf2JdSQYUeScvJf4NSs=", "serverKey" : "M9e57gCxHnfaE1xvxFLu1g7RrF13+ZTsVE5zcVw6PWU=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }

#管理员将admin数据库 切换为 commonuser数据库
> use commonuser
switched to db commonuser

#管理员 在 commonuser 中创建普通用户 dan
> db.createUser({user:"dan",pwd:"love",roles:[{role:"readWrite",db:"commonuser"}]})
Successfully added user: {
	"user" : "dan",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "commonuser"
		}
	]
}
>

2.2.5、使用普通用户

因为mongodb已经配置过环境变量,所以在任意目录下均可启动

xshell新开node节点,mongodb客户端已经成功连接到mongodb服务器

mongodb 设置root 用户 mongodb 用户权限管理_mongodb_10

2.2.6、切换到commonuser数据库

因为我们是在 commonuser 数据库中创建的 dan 普通用户,所以需要先切换到 commonuser 库

# 切换到普通数据库 commonuser
> use commonuser
switched to db commonuser
>

2.2.7、登录普通用户

如果我们不登录会发现无法对该数据库进行插入操作,因为缺少用户认证

# 启动mongodb服务器
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 24758
child process started successfully, parent exiting

# 启动mongodb客户端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("de519bc5-c441-4baa-ada7-767df13b294b") }
MongoDB server version: 4.2.1

# 切换到 普通数据库commonuser
> use commonuser
switched to db commonuser

# 向commonuser数据库中插入数据,发生报错,原因是没有用户认证过
> db.commonuser.insert({id:"100"})
WriteCommandError({
	"ok" : 0,
	"errmsg" : "command insert requires authentication",
	"code" : 13,
	"codeName" : "Unauthorized"
})

# 用户认证
> db.auth("dan","love")
1

# 再次向数据库中插入数据,成功
> db.commonuser.insert({id:"100"})
WriteResult({ "nInserted" : 1 })

# 认证成功后,通过该用户操作 commonuser 库,该用户对 commonuser 库具有读写操作
> db.commonuser.find()
{ "_id" : ObjectId("61483e205e6e3f2e7a47e6d5"), "id" : "100" }
>

2.3、更新用户角色

如果我们需要对已存在的用户的角色做修改,那么我们可以使用 db.updateUser()函数来更新用户角色,注意,该函数需要当前用户具有 userAdminAnyDatabase 或者更高的权限

2.3.1、更新角色语法格式

db.updateUser(“用户名”,{“roles”:[{“role”:“角色名称”},{“更新项2”:“更新内容”}]})

2.3.2、需求

目前 pipi 管理员用户只具备 userAdminAnyDatabase 用户管理角色,我们为该用户添加一个 dbAdminAnyDatabase 数据库管理角色

2.3.3、更新角色

# 启动mongodb服务端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

about to fork child process, waiting until server is ready for connections.
forked process: 29232
child process started successfully, parent exiting

# 启动mongodb客户端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d9f9d808-4de5-4fa9-9712-1b2ebadc2805") }
MongoDB server version: 4.2.1

# 切换为admin数据库
> use admin
switched to db admin

# 用户认证 管理员用户
> db.auth("pipi","love")
1

# 更新用户角色信息,此处是更新用户权限
> db.updateUser("pipi",{roles:[{"role":"userAdminAnyDatabase","db":"admin"},{"role":"dbAdminAnyDatabase","db":"admin"}]})

# 查询用户信息
> show users
{
	"_id" : "admin.pipi",
	"userId" : UUID("3c779c02-d43e-48a7-aa87-a3204c9ba2ef"),
	"user" : "pipi",
	"db" : "admin",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		},
		{
			"role" : "dbAdminAnyDatabase",
			"db" : "admin"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

# 更新用户密码,两种方式
> db.updateUser("pipi",{"pwd":"root"})
> db.changeUserPassword("pipi","love")

2.4、更新用户密码

更新用户密码有两种方式
使用db.updateUser()函数更新密码,也可以更新用户角色
使用db.changeUserPassword()函数只能用于更新密码

2.4.1、更新密码方式一

使用db.updateUser()函数将 pipi 用户的密码修改为 root

语法格式
db.updateUser(“用户名”,{“pwd”:“新密码”})

# 将admin数据库的管理员pipi的密码改为root
> db.updateUser("pipi",{"pwd":"root"})

如果未提示任何信息则表示更新成功,退出当前客户端重新连接认证即可

2.4.2、更新密码方式二

使用db.changeUserPassword()函数将管理员用户 pipi 的密码修改为 love

语法格式
db.changeUserPassword(“用户名”,“新密码”)

> db.changeUserPassword("pipi","love")

验证admin库的管理员用户pipi的密码是否更新

# 更新管理员密码,两种方式
> db.updateUser("pipi",{"pwd":"root"})
> db.changeUserPassword("pipi","love")

# ctrl+c 退出 mongodb客户端,mongodb服务端依然开启中,除非kill -9 进程 才可杀死
> ^C
bye

# 再次重新连接mongodb客户端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("dcdbd1ac-5e05-4ca8-a450-06b7ed013884") }
MongoDB server version: 4.2.1

# 切换到 admin 数据库
> use admin
switched to db admin

# 用户认证成功,说明管理员密码更新成功
> db.auth("pipi","love")
1
>

如果未提示任何信息则表示更新成功,退出当前客户端重新连接认证即可

2.5、删除用户

通过 db.dropUser() 函数可删除指定用户,删除成功后返回true,在删除用户时需要切换到创建用户时所指定的数据库中才可以删除,注意:需要使用具有 userAdminAnyDatabase 角色管理员用户才可以删除其他用户

2.5.1、需求

使用 db.dropUser() 函数将 dan 用户删除

2.5.2、切换数据库

dan 用户在 commonuser 数据库中,所以需要先切换到 commonuser 数据库

# 切换到 普通数据库commonuser中
> use commonuser
switched to db commonuser

2.5.3、通过函数删除用户

注意:需要先进入admin数据库,用户认证是管理员,再切换到普通数据库,删除指定的用户

# 启动mongodb服务端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongod --config /usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.2.1/etc/mongodb.conf 

# 启动mongodb客户端,连接到mongodb服务端
[root@iZ2ze5v2vdwv6veyksylhxZ bin]# ./mongo

MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a136cdc3-11b0-41c9-b58d-30a3fd283238") }
MongoDB server version: 4.2.1

# 切换数据库为admin
> use admin
switched to db admin

# 用户认证 管理员
> db.auth("pipi","love")
1

# 切换数据库为 普通数据库commonuser
> use commonuser
switched to db commonuser

# 删除指定用户
> db.dropUser("dan")
true
>