MongoDB logo

MongoDB is extremely easy to install and run. If you are not able to make it work maybe you could feel more confortable using Access or even excel. Well, sorry for that. This short article is but a quick and dirty guide to enable basic authentication in mongodb, and how to create one database with its own user (not a superadmin) with just read/write permissions.

If you run mongod without parameters, you will not have any auth mechanism protecting your data. That could be fine when you are in a testing environment or in your own laptop playing around, but not in production or in any publicly reachable site.

/opt/mongodb/bin/mongod --fork --syslog --dbpath /data/db --smallfiles --auth --bind_ip 127.0.0.1

You could also just apply iptables or any other firewall system to prevent intrusions.

Maybe you have noticed that bind_ip 127.0.0.1 parameter. In doing so mongod will be available only for local connections which but only in certain conditions: obviously your program must reside in the same machine. In addition to that, mongod should be a single and isolated instance. That means that this configuration is impossible in replica sets or sharding scenarios. And by the way, if you need to manage MongoDB instance you need a program for it; something like the phpmyadmin for mysql, for instace http://www.phpmoadmin.com/. With --fork the mongod process will go to background, --syslog will send all log messages to /var/log/whatever you have configured in syslog, --dbpath indicates the directory where MongoDB data files are and --smallfiles comes in handy for testing or development environments becauses it reduces the size of data files and journal files.

User and roles

Apart from some authentication systems, MongoDB has users and roles which can be applied to different databases. First, let's see how to create an admin user for admin database with god-like (root) permissions. It's also explained here.

Root permissions for all mongo databases:

use admin
db.createUser(
  {
    user: "admin",
    pwd: "KeepASecret",
    roles: [ "root" ]

  }
)
Successfully added user: { "user" : "admin", "roles" : [ "root" ] }

Now mongodb will not show you anything. Logout and log in again, this time using those credentials.

root@usurbil:# mongo -u admin -p KeepASecret admin
MongoDB shell version: 2.6.1
connecting to: admin
>

To check the permissions for a certain user:

db.runCommand(
  {
    usersInfo:"admin",
    showPrivileges:true
  }
)
One user just for one database

Somo basic permissions for just one db:

use myotherdb
db.createUser(
  {
    user: "myotherdbuser",
    pwd: "KeepASecret",
    roles: ["readWrite","dbAdmin"]
  }
)

That's it, fisrt we access admin database and then we run db.createUser command with obvious options in json sintax. If anything fails we can just stop mongod and re-run it without the --auth flag. If you try to access with your mongoshell using this admin user you'll get:

root@linux:# mongo  -u admin -p wrongpass admin
MongoDB shell version: 2.6.1
connecting to: admin
2014-07-18T01:32:04.702+0200 Error: 18 { ok: 0.0, errmsg: "auth failed", code: 18 } at src/mongo/shell/db.js:1210
exception: login failed
root@linux:#

We could also log without any user and authenticate from the mongo shell

root@linux:# mongo --host localhost admin
MongoDB shell version: 2.6.1
connecting to: localhost:27017/admin
> db.auth({user: 'admin',pwd:'KeepASecret'})

Changing password

To change the password, enter as admin, change to the database of that user and execute changeUserPassword command

> use myotherdb
switched to db myotherdb
> db.changeUserPassword("myotherdbuser", "1234567")

Updating permissions

Database access are stored in collections of course, in db.system.users. So we can just execute update queries to add new roles, which is but an array where we can push or pop values.

 db.system.users.update({_id:"admin.admin"},{$push:{"roles":{"role":"root","db":"mytotherdb"}}})

To be honest, this is the kind of post that I use as a reminder. Hope that anybody reading this finds it useful. ;)