Analysis of security authentication of mongodb

Time:2022-3-18

1、 User and role permissions of mongodb

In order to force user access control (user authentication), you need toMongoDBUse option when instance starts--authOr add in the specified startup profileauth=true

  • Enable access control:MongoDBRole based access control is used(Role-Based Access Control,RBAC)To manage user access to instances. By granting one or more roles to users, users can control their access to database resources and database operations. Before assigning roles to users, users cannot access instances.
  • Role: inMongoDBIn, users are granted the operation permission of corresponding database resources through roles. The permission in each role can be displayed and specified, or by integrating the permissions of other roles, or both.
  • Permission: permission consists of the specified database (resource) and the actions allowed on the running resource. Resources include: database, collection, partial collection and cluster; Actions include: add, delete, modify and query (crud) operations on resources.

One or more existing roles can be included in the role definition, and the newly created role will inherit all the permissions of the included role. In the same database, newly created roles can inherit the permissions of other rolesadminThe role created in the database can inherit the permissions of the role in any other database.

You can view role permissions through the following commands:

#Query all role permissions (only user-defined roles) 
> db.runCommand({ rolesInfo: 1 })

#Query all role permissions (including built-in roles)
> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })

#Query the permissions of a role in the current database 
> db.runCommand({ rolesInfo: "<rolename>" })

#Query the specified role permissions in other databases
> db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }

#Query multiple role permissions
> db.runCommand({ 
	rolesInfo: [ 
		"<rolename>", { role: "<rolename>", db: "<database>" },
		...
	] 
})

Example:

1.1. View all built-in roles


> db.runCommand({rolesInfo:1, showBuiltinRoles:true})
{
	"roles" : [
		{
			"role" : "__queryableBackup",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "__system",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "backup",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "clusterAdmin",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "clusterManager",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "clusterMonitor",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "dbAdmin",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "dbAdminAnyDatabase",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "dbOwner",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "enableSharding",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "hostManager",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "read",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "readAnyDatabase",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "readWrite",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "readWriteAnyDatabase",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "restore",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "root",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "userAdmin",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		},
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin",
			"isBuiltin" : true,
			"roles" : [ ],
			"inheritedRoles" : [ ]
		}
	],
	"ok" : 1
}

1.2. Common built-in roles

  • Database user role:readreadWrite
  • Database management role:dbAdmindbOwneruserAdmin
  • Cluster management role:clusterAdminclusterManagerclusterMonitor
  • All database user roles:readAnyDatabasereadWriteAnyDatabaseuserAdminAnyDatabasedbAdminAnyDatabase
  • Backup recovery role:backuprestore
  • Superuser role:root
  • Internal role:system

Role description:

role Permission description
read You can read any data in the specified database.
readWrite You can read and write any data in the specified database, including creating, renaming and deleting collections
readAnyDatabase You can read any data in all databases (except database config and local)
readWriteAnyDatabase You can read and write any data in all databases (except database config and local)
userAdminAnyDatabase Users can be created and modified in the specified database (except for database config and local)
dbAdminAnyDatabase You can read any database and clean up, modify, compress, obtain statistics, check and other operations on the database (except database config and local)
dbAdmin You can read the specified database, clean up, modify, compress, obtain statistical information, perform inspection and other operations on the database
userAdmin Users can be created and modified in the specified database
clusterAdmin It can manage the whole cluster or database system
backup Minimum permission to back up mongodb data
restore Permission to restore mongodb data (except system.profile Collection) from backup files
root Super account

2、 Single instance environment

2.1. Create user

The user creation format is as follows:

db.createUser({
	user:"<name>",
	pwd:"<password>",
	customData:{<any Object Data},
	roles:[
		{role:"<role>",db:"database"},
		...
	]
})

remarks:
1) User: new user name
2) PWD: new user password
3) Customdata: stores some user-defined data related to users, which can be ignored
4) Roles: data type to configure user permissions

Example: create an administrator account


# mongo --host=10.10.10.11 --port=27017
> show dbs;
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.000GB
> 
> use admin
switched to db admin
> 
> db.createUser({"user":"root","pwd":"123456","roles":[{"role":"root","db":"admin"}]});
Successfully added user: {
	"user" : "root",
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	]
}

View user:

#Method 1
> use admin;
switched to db admin
> 
> show users;
{
	"_id" : "admin.root",
	"userId" : UUID("d7280144-2886-45eb-95f3-1965be4eb7fe"),
	"user" : "root",
	"db" : "admin",
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

#Method 2
> use admin;
switched to db admin
> 
> show tables;
system.users
system.version
> 
> db.system.users.find()
{ "_id" : "admin.root", "userId" : UUID("d7280144-2886-45eb-95f3-1965be4eb7fe"), "user" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "u2nQBHuC2P367Qo5mLhcRw==", "storedKey" : "0ccLsqhpWUyCdAoQKZQNNHwvj9g=", "serverKey" : "9Qxfsw+GCQMwUuyz9AlKRAX6zx0=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "rxajlRAv8zteEMm6r2Wx8GFY1ShBeLjHUqJ7iA==", "storedKey" : "T9z/0GJ21cxJ4CvnNL+PBGkTYwdPu9YxmRo1CQ2tGp0=", "serverKey" : "UBVuzHOxfKADUdpxIhRBab2HwPdLhNL2yUZzyTXFRt0=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ]

2.2. Server start authentication

To modify a profile:

# vim /usr/local/mongodb/conf/mongodb.conf
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongodb.log
bind_ip=0.0.0.0
port=27017
logappend=1
fork=1
Auth = true # enable authentication

Restart service:


# ps -ef |grep mongod
root       6991      1  0 19:46 ?        00:00:10 mongod -f /usr/local/mongodb/conf/mongodb.conf
root       7438   6395  0 20:14 pts/1    00:00:00 grep --color=auto mongod
# kill -2 6991 
# 
# mongod -f /usr/local/mongodb/conf/mongodb.conf

Login test:

# mongo --host=10.10.10.11 --port=27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("cb337048-a9c8-45ae-99aa-b0cb8cc7a163") }
MongoDB server version: 4.4.1
>Show DBS # view
> 
>Use admin # switch to admin Library
switched to db admin
> db. auth("root","123456") 	# Conduct certification
1
> show dbs;
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.000GB

Add an ordinary user:

Creating ordinary users can be added when authentication is not turned on or after authentication is turned on. However, after authentication is turned on, you must use the existing operationadminUsers of the library can only operate after logging in and authenticating. The bottom layer is to save the user information in theadminCollection of databasessystem.usersYes.

#Create (switch) the database articledb to be operated in the future
> use articledb
switched to db articledb
> 
> db.createUser({user:"user1",pwd:"1234",roles:[{role:"readWrite",db:"articledb"}]})
Successfully added user: {
	"user" : "user1",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "articledb"
		}
	]
}
#Test available
> db.auth("user1","1234")
1

2.3 client login authentication

Method 1

Connect first, before authentication:


# mongo --host 10.10.10.11 --port 27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("4efbbc03-31b7-45ff-8b3a-5ce6f76ff1ca") }
MongoDB server version: 4.4.1
> use admin
switched to db admin
> db.auth("root","123456")
1
> show dbs
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.000GB

Method 2

Authentication when connecting:


# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("0848b5d0-fb56-40eb-9b37-542682fd6ada") }
MongoDB server version: 4.4.1
......
> 
> show dbs
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.000GB

Parameter Description:

  • --host: connected host address
  • --port: connected port
  • --authenticationDatabase: specifies which library to connect to. When the login is to specify the user password, you must specify the corresponding database!
  • -u: username
  • -p: password

3、 Replica set environment

For the builtmongodbFor replica set, for security, start security authentication and log in with account password.

Two aspects need to be configured to perform access control on replica sets:

1) Internal authentication is used between the replica set and each node member of the shared cluster. You can use secret key files orx.509Certificate. The secret key file is relatively simple.

2) Connect to using clientmongodbWhen clustering, access authorization can be turned on. Access outside the cluster. For example, when connecting through visual client or code, authorization needs to be turned on.

3.1. Add management account

Add a management account in the master node and the replica set will be synchronized automatically.


myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> db.createUser({user:"root",pwd:"123456",roles:[{role:"root",db:"admin"}]})
Successfully added user: {
	"user" : "root",
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	]
}

remarks:

This step can also be started after authentication, but it needs to passlocalhostUsers can only be added after login, and the user data will be automatically synchronized to the replica set. Other users created later have been created by the super tube user.

3.2. Create a key file for replica set authentication

Generate a key file into the current folder.

You can use any method to generate a secret key file, for exampleopensslGenerate a password file, and then usechmodTo change file permissions, which only provides read permissions for all files.


# openssl rand -base64 90 -out ./mongo.keyfile
# chmod 400 ./mongo.keyfile 
# ll mongo.keyfile 
-r--------. 1 root root 122 Nov 17 16:27 mongo.keyfile

remarks:

All replica set nodes must use the same replicakeyfileGenerally, it is generated on one machine and then copied to other machines, and must have read permission, otherwise an error will be reported in the future:permissions on /mongodb/replica_sets/myrs_27017/mongo.keyfile are too open

Generally, it is placed together with the configuration file to facilitate searching. All herecopyTo the configuration file directory of each node


# cp mongo.keyfile /data/replica_sets/myrs_27017/
# cp mongo.keyfile /data/replica_sets/myrs_27018/
# cp mongo.keyfile /data/replica_sets/myrs_27019/

3.3. Modify the configuration file and specify the keyfile

Edit the of several services respectivelymongod.confFile, add relevant contents:

# vim /data/replica_sets/myrs_27017/mongod.conf
security:
    #Keyfile authentication file
    keyFile: /data/replica_sets/myrs_27017/mongo.keyfile
    #Enable authentication mode operation
    authorization: enabled

# vim /data/replica_sets/myrs_27018/mongod.conf
security:
    #Keyfile authentication file
    keyFile: /data/replica_sets/myrs_27018/mongo.keyfile
    #Enable authentication mode operation
    authorization: enabled

# vim /data/replica_sets/myrs_27019/mongod.conf
security:
    #Keyfile authentication file
    keyFile: /data/replica_sets/myrs_27019/mongo.keyfile
    #Enable authentication mode operation
    authorization: enabled

3.4. Restart replica set

If the replica set is on, turn off each of the replica sets separatelymongod, starting from the secondary node. Until all members of the replica set are offline, including any arbiter. The master node must be the last member to shut down to avoid potential rollback.


# ps -ef |grep mongod
root       2649      1  1 11:20 ?        00:04:44 mongod -f /data/replica_sets/myrs_27017/mongod.conf
root       2728      1  1 11:20 ?        00:05:21 mongod -f /data/replica_sets/myrs_27018/mongod.conf
root       4534      1  0 14:13 ?        00:01:07 mongod -f /data/replica_sets/myrs_27019/mongod.conf

# kill -2 2649 4534 2728

Start replica sets separately:


# mongod -f /data/replica_sets/myrs_27017/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 6287
child process started successfully, parent exiting
# 
# mongod -f /data/replica_sets/myrs_27018/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 6365
child process started successfully, parent exiting
#
# mongod -f /data/replica_sets/myrs_27019/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 6456
child process started successfully, parent exiting

View progress:


# ps -ef |grep mongo
root       6287      1  3 16:40 ?        00:00:02 mongod -f /data/replica_sets/myrs_27017/mongod.conf
root       6365      1  3 16:41 ?        00:00:02 mongod -f /data/replica_sets/myrs_27018/mongod.conf
root       6456      1  2 16:41 ?        00:00:01 mongod -f /data/replica_sets/myrs_27019/mongod.conf

3.5 connection test

Connect master node test:

Connect first and then authenticate


# mongo --host 10.10.10.11 --port 27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e1218d07-5094-468d-bdfe-f1d3e3815281") }
MongoDB server version: 4.4.1
myrs:PRIMARY> show dbs
myrs:PRIMARY> db.auth("root","123456")
1
myrs:PRIMARY> show dbs
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.001GB
test        0.000GB

Authentication when connecting:


# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
---
myrs:PRIMARY> show dbs
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.001GB
test        0.000GB

Connect replica node test:

# mongo --host 10.10.10.11 --port 27018 --authenticationDatabase admin -u root -p 123456
myrs:SECONDARY> show dbs 	# To view the database, you cannot view it here because the default replica node cannot query data and you need to enable query permission
uncaught exception: Error: listDatabases failed:{
	"topologyVersion" : {
		"processId" : ObjectId("5fb38ca9ae9c791f8008eb9a"),
		"counter" : NumberLong(4)
	},
	"operationTime" : Timestamp(1605603187, 1),
	"ok" : 0,
	"errmsg" : "not master and slaveOk=false",
	"code" : 13435,
	"codeName" : "NotMasterNoSlaveOk",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1605603187, 1),
		"signature" : {
			"hash" : BinData(0,"hCt+wCrLo2uwZucZsLN0id+Rnh0="),
			"keyId" : NumberLong("6893051287466672133")
		}
	}
} :
[email protected]/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
[email protected]/mongo/shell/mongo.js:99:12
[email protected]/mongo/shell/utils.js:937:13
[email protected]/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
myrs:SECONDARY> 
myrs:SECONDARY> rs.secondaryOk() 	# Turn on replica set read permission
myrs:SECONDARY> 
myrs:SECONDARY> show dbs 	# View again
admin       0.000GB
collectest  0.000GB
config      0.000GB
local       0.001GB
test        0.000GB

3.6. Add ordinary users

Add ordinary users who have read and write permissions to the specified library:

//Connect master node
# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
myrs:PRIMARY> use collectest 	# Switch to the collectest Library
switched to db collectest
myrs:PRIMARY> 
myrs:PRIMARY> db. createUser({user:"u_test",pwd:"123",roles:[{role:"readWrite", db:"collectest"}]}) 	# Create user u_ Test has read and write permissions on the collectest library

Successfully added user: {
	"user" : "u_test",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "collectest"
		}
	]
}
myrs:PRIMARY>

Log in and query data using ordinary users:

# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase collectest -u u_test -p 123
...
myrs:PRIMARY> 
myrs:PRIMARY> show dbs
collectest  0.000GB
myrs:PRIMARY> 
myrs:PRIMARY> use collectest
switched to db collectest
myrs:PRIMARY> 
myrs:PRIMARY> show collections
collectest
myrs:PRIMARY> 
myrs:PRIMARY> db.collectest.find()
{"_id": objectid ("5faa3432f6e79c62c00e4d72"), "name": "Zhang San", "sex": "male", "age": 22, "userid": 1001, "createdatetime": Isodate ("2020-11-10t06:33:22.459z")}
{"_id": objectid ("5facec10cca53c48154d261c"), "name": "Xiaobai", "sex": "female", "age": 20, "userid": 1002, "createdatetime": Isodate ("2020-11-12t08:02:24.915z")}
{"_id": objectid ("5facf32dfb5fe16aaf699d7d"), "name": "little Hey", "sex": "female", "age": 21, "userid": 1002, "createdatetime": Isodate ("2020-11-12t08:32:45.919z")}
myrs:PRIMARY>

#If you query a library that ordinary users do not have permission, you will be prompted with a warning and cannot view it successfully.
myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus

The above is the detailed analysis of mongodb security authentication. For more information about mongodb security authentication, please pay attention to other relevant articles of developeppaer!

Recommended Today

Security problems of JSP Application

1、 OverviewWhen network programming becomes more and more convenient, the system function becomes more and more powerful, but the security decreases exponentially. I’m afraid this is the misfortune and sadness of network programming. Various dynamic content generation environments have prospered www. their design goal is to give developers more power and end users more convenience. […]