The MongoDB database server is well-known for its unmatched capabilities for processing large NoSQL data. Its latest performance improvements are always under the spotlights and probably not a single MongoDB user has missed the recent news about the change of its default storage engine to the more powerful WiredTiger. At the same time, its security features are less known and often neglected. That's why the purpose of this article is MongoDB security.

Prerequisites

Before following this tutorial, please make sure you complete the following prerequisites:

  • A Ubuntu 14.04 server.
  • Preferably a non-root sudo user.
  • MongoDB installed and configured.
  • Except otherwise noted, all of the commands that require root privileges in this tutorial should be run as a non-root user with sudo privileges.

Step 1 - Requiring authentication

By default, in MongoDB you can manage any database without authentication. Obviously, this is quite insecure even though the MongoDB service doesn't listen on external interfaces and an attacker will need local access to the server first.

Let's start securing MongoDB by creating an admin user who can manage all the databases. This user will have the role userAdminAnyDatabase.

To create this super admin user, log in MongoDB and connect to the admin database with the command:

mongo admin

As you can see, you don't need a password for operating MongoDB at this point. You don't even need Linux sudo rights and you can run the command as a normal user.

Now let's create the user mongoadmin with password S3cr3t11.@ with the query:

> db.createUser(
{
user: "mongoadmin",
pwd: "S3cr3t11.@",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)

The name mongoadmin is arbitrary and you can use any other to your liking. A good security practice is to pick up a non-standard name, different from the standard admin. Thus, in the case of a brute-force attack, the attacker will have to guess not only your password but also username.

The output of the above command should confirm the successful creation of the user like this:

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

We'll continue working with the MongoDB shell and exit it later.

So far we have a super admin user who should be used only for administration, i.e. tasks like creating other users and granting them privileges. By default, you cannot and should not use this user to connect to other databases. This might be something new for people acquainted with other database systems where the super admin (root) has limitless privileges.

In addition to that user, let's create another one for connecting to a database. For the example we'll use a database called newdb and add to it an user with read/write permissions called newdbUser.

In the MongoDB shell switch to the newdb with the command:

> use newdb

If you don't have already such a database, it will be automatically created for you. Then add its user with the command:

> db.createUser(
{
user: "newdbUser",
pwd: "S0m3Pass",
roles: [
{ role: "readWrite", db: "newdb" },
]
}
)

You should see again a confirmation like this:

Successfully added user: {
"user" : "newdbUser",
"roles" : [
{
"role" : "readWrite",
"db" : "newdb"
}
]
}

After we have these two users created, we can enable authentication in MongoDB. For this purpose exit the MongoDB shell and start editing the main MongoDB configuration file /etc/mongod.conf such as with vim or nano. Add the following two lines there:

security: