Thursday, October 9, 2014

MongoDB security and user access control

MongoDB does not offer as fine grained a security model as traditional databases. Never the less what it provides is sufficient as long as best practices are followed and some care is taken in securing the system.
MongoDB offers two levels of access control – system (global) and per database. For each of these types, users can be assigned a series of roles which determine the actions they can perform. The model is pretty simple and straight forward and allows for a least-privilege approach. The only shortcoming (at the time of writing) is that the roles are a little broad. In the future I would really like to see the ability of setting more fine grained restrictions on actions or even the ability to create your own role groups with action rules.

Enabling authentication

The first thing to do before you can start making use of mongo’s UAC features it to enable authentication. Usually this is disabled by default.
This can be enabled either by editing your mongodb.conf file and adding the line
auth = true

You can also start mongod with the auth parameter.

Creating an admin user

Out of the box mongo has no admin user set. Hence once you enable authentication you will be able to gain privileged access via a local mongo shell until an admin user has been created.
Start the shell and type:
use admin
db.addUser({ user:"admin", pwd:"secretpassword", roles:["dbAdminAnyDatabase","clusterAdmin"]})

This will create a user admin with the password secretpassword and grant that user dbAdminAnyDatabase and clusterAdmin roles. I recommend granting the primary admin user both of these roles as they will enable you to perform any action you want on any database.
Note: If you do not set clusterAdmin you will get an unauthorised error when you try to drop a database.
Now that you have an admin account enabled you will be required to authenticate before you can perform any actions.

Creating a database user

You can now add a user to any database and set access restrictions.
First select the database you wish to add a user to.
use example
We are now using the example database. Adding a user is exactly the same to how we created an admin user:
db.addUser({ user:"rwUser", pwd:"password", roles:["readWrite"] })
This will create a user rwUser which will have read/write access to the current database.

Authenticating

Before you can perform an action either globally or within a given database you will need to authenticate.
You can authenticate as a global user or a database user by selecting the appropriate database. Then you can authenticate by typing:
db.auth("rwUser","password")
You will get a response code of 1 for success and 0 for fail. Once authenticated you will be able to execute any action your roles allow you.

User roles

At the time of writing Mongo (2.4) has the following roles:

Database User Roles

  • read
  • readWrite
  • dbAdmin
  • userAdmin

System User Roles

  • clusterAdmin
  • readAnyDatabase
  • readWriteAnyDatabase
  • userAdminAnyDatabase
  • dbAdminAnyDatabase
For detailed information regarding each role please refer to User Privilege Roles in MongoDB in the MongoDB Official Documentation.

Remove a user

You can remove both database and system users in the same way. First select either a specific logical database or the system admin database. Then type:
db.removeUser("testuser")
Which will remove the user testuser.
Note: You technically should not be able to remove the admin user…

Changing passwords

If you wish to change a user password select either a specific logical database or the system admin database. Then type:
db.changeUserPassword("testuser", "newpassword")
Which will update the user testuser with the new password newpassword.

Updating users

If you wish to update an existing user – for instance to change their username or update their roles, you can do so by performing an update against the system.users collection of either either a specific logical database or the system admin database. This works exactly like a standard update() and the same rules and parameters apply.
Here are some typical update scenarios you might wish to perform:

Update a username

use example
db.system.users.update({ user:"testUser" }, { $set:{ user:"tastyUser" } })

Add an additional role to a user

use example
db.system.users.update({ user:"testUser" }, { $push:{ roles:"userAdmin" } })

Remove a user role

use example
db.system.users.update({ user:"testUser" }, { $pull:{ roles:"dbAdmin" } })

No comments:

Post a Comment