Securing MongoDB with Authentication and Authorization using Node.JS and Mongoose on Ubuntu

One of the nice things about MongoDB is that it doesn't force your to deal with account management; you simply install it and you can immediately start cramming it full of data anonymously.

But if you need to access a database remotely, or you just want an extra layer of security for your data, setting up MongoDB user accounts and restricting access is very simple and highly recommended.

Step 1) Create an administrator account

It's a swell idea to create an account with access to all databases, and then use this account to create more restricted accounts for users and applications.

Each user is stored in and authenticated against a single database, though you can grant it access to other databases using the 'roles' attribute. When creating a user, it will be created in the current database, so let's switch to the 'admin' database to store our admin user in:

use admin;

To create a user in the currently selected database, we call db.createUser() and specify 'user', 'pwd', and 'roles' attributes. To create a root user (one with full privileges across all databases) named 'admin' with password 'pass':

db.createUser({
  user : "admin",
  pwd  : "pass",
  roles: [
    { 
      role: 'root', db: 'admin'
    }
  ]
});

You can see that each role object in the roles array requires a role name and a database name. For some reason, you still have to specify a database even if the role allows access to all databases.

There are a ton of Built-in MongoDB user roles, and they will meet most of your needs. If they do not, please be aware that you can create your own custom user roles. Useful roles include 'read', 'readWrite', 'dbAdmin', 'userAdmin', 'backup', 'restore', and 'root'

Step 2) Test your administrator account

mongo admin -u admin -p pass

Even though this user has full access to all databases, authentication will fail if we do not connect to the admin database. This is because the admin user is stored in the admin database, and mongo needs to be told which database the user is stored in before it can authenticate them. By default, mongo assumes the user is stored in the database that you are connecting to, but you can override this assumption by using the --authenticationDatabase flag

mongo -u admin -p pass --authenticationDatabase admin

Step 3) Create a restricted user for your application

It's not the most wise strategy to use your root account for your application. Each user and application should have their own account that is restricted to access only the data that they need to function.

For this we will assume that you have a database named 'app' that you use for your web application, and your application needs to read and write to 'app'.

use app;

db.createUser({
  user : "appuser",
  pwd  : "apppass",
  roles: [
    { 
      role: 'readWrite', db: 'app'
    }
  ]
});

Step 4) Force authorization

Right now, your mongo database accepts authentication, but authentication is not required. In order to force users to authenticate, we have to enable it in the /etc/mongod.conf configuration file

FOR MONGODB 3.0 AND ABOVE add these lines:

security:
  authorization: enabled

FOR MONGODB 2.X add this line:

auth = true

Any changes to your config file require a restart before they will take effect:

sudo service mongod restart

Step 5) Connect with Node.js / Mongoose.js

var fs = require('fs')
  , mongoose = require('mongoose')
  , mongoUri = "mongodb://appuser:apppass@127.0.0.1:27017/app"
  ;

mongoose.connect(mongoUri);

All of the magic here is contained in the mongo connection string. This same connection string also works with the native mongodb driver.

Here we are connecting the same database that the user is stored in (app), so it should authenticate properly. To connect to a different database that the user is not stored in, we can add the 'authSource' attribute. Here we are connecting to the 'app2' database with 'appuser' who is stored in the 'app' database:

mongodb://appuser:apppass@127.0.0.1:27017/app2?authSource=app"

Step 6) [Optionally] allow external connections

If you need to connect to your database from another machine in the network, you have to tell mongo to bind to an external IP address.

FOR MONGODB 3.0 AND ABOVE comment the bindIp line:

net:
  # bindIp: 127.0.0.1

FOR MONGODB 2.X comment the bind_ip line:

# bind_ip = 127.0.0.1

And restart:

sudo service mongod restart

Step 7) [Optionally] encrypt your MongoDB traffic with TLS/SSL

7 comments:

  1. Thanks a lot!!!
    I got this done correctly after spending an entire day looking at various articles on the web.
    Awesome Article. To the Point!!!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. hello my mongodb not config file how to use

    ReplyDelete
  4. Very informative post for us, thanks for sharing.

    Gmail Support.

    ReplyDelete
  5. As Indicated by Web Development Company in UK Point of View. Web development is a piece of business these days regardless of on the off chance that you are working with worldwide introduction or you are only a startup. Use of computerized promoting can be best delighted in web world and it is an awesome method to advance a brand.

    ReplyDelete
  6. According to the Top video Development Company in UK A decent quality video making company dependably conveys the best item. A business video producer utilizes gear and experienced experts who make 3D and 2D liveliness videos in least time and addresses the customer's issues by sparing the time and cash giving top notch videos.

    ReplyDelete