mongo

Sep 052013
 

While operating a MongoDB cluster, it can often be useful in maintenance scripts to check whether a host is the primary or secondary (master or slave). This is easy to do, and can be done without having to authenticate against the database. Scripts can be made simpler as there is no need to shield the login credentials, as there aren’t any.

When one connects a Mongo database process without credentials, using the “mongo” client command, the implicit “test” database is used. This is a default, and a kind of empty chroot database. Even though it’s an empty database, it still has read-only access to replica information. This can be very handy when automating deployment and monitoring scripts.

There are two commands in particular that are useful for determining the status of a replica set member. These are demonstrated in the following console example, which is fairly self-explanatory.

$ mongo localhost:27017
connecting to: localhost:27017/test
> db.isMaster().secondary
false
> db.isMaster().ismaster
true

This could also be executed non-interactively like this:

mongo localhost:27017 --quiet --eval 'db.isMaster().secondary'

Shell Script Snippet: wait for replica synchronization to finish

When resynchronizing a replica set slave, it will report its status as RECOVERING until it completes, at which point it becomes SECONDARY. The simple example below demonstrates a block of bash to test for this.

while [ "$RESULT" != "true" ]; do
   RESULT=$(mongo localhost --quiet --eval 'db.isMaster().secondary');
   sleep 5;
done

This is over-simplified to demonstrate the logic. In a real-world script you’d have an exit clause to prevent an endless loop in the case when the replica node never recovers.

Other useful commands can be discovered while browsing the mongo console. Find these using commands of the format:

  db.help()


Matt Parsons is a freelance Linux specialist who has designed, built and supported Unix and Linux systems in the finance, telecommunications and media industries.

He lives and works in London.

Jun 062012
 

There are many occasions where you get locked out of a Mongo DB database. It could be that the admin password is unknown, or that the only admin user that exists is “read-only” (something that Mongo permits you to do). Fortunately, it’s fairly straightforward to remove the admin database safely and recreate the admin user.

Mongo DB has an idiomatic, not to mention pragmatic approach to user authorization. Access to the database is simplified, and not particular granular, with the idea that access control should be passed more to the connecting application itself. Thus, the default access control is to have no users at all. You need to create an “admin” user account if you want one. Nothing, however enforces this.

One creates an admin user by creating a user on the “admin” database, after logging in to Mongo:

  # mongo localhost
MongoDB shell version: 2.0.2
connecting to: localhost/test
  > use admin
switched to db admin
  >  db.addUser("admin","Password")

And that’s it.

Once this user exists, then every time you login to the database, you need to authenticate, like this:

  # mongo localhost
MongoDB shell version: 2.0.2
connecting to: localhost/test
  > use admin
switched to db admin
  mongo> db.auth("admin","Password")

Failure to authenticate will allow you your connection, but no access to any data. Once again, it’s the fact of the existence of the admin user which enforces access control, as well as the following option in the Mongo DB config file:

  auth=true

Solution

This solution will focus on removal of the admin user in a replica set, because it’s slightly more complicated, and slightly more interesting. If you’re just running a single node, the procedure is considerably easier. Just ignore the cluster steps.

Stop all Mongo processes running in the replica set. These will probably be running with the command line or config file option of “replSet”. Check by running “ps” or checking the /etc/mongod.conf file.

When no Mongo replicas are running, perform the following procedure on each node in turn. You’ll need to bring the Mongo process up at one point, but it is vital that only one replica is running at any one time, otherwise the configuration will get resynchronised from another node, and you don’t want that. You want it changed.

On each node

Change to the mongo directory where the data files reside, possibly /var/lib/mongo but specified in the configuration file by the dbPath parameter.

  # cd /var/lib/mongo

Move the admin.* files somewhere else to back them up.

  # mv admin.* /tmp

It’s that simple. Deleting these datafiles will have removed the admin credentials from the database.

Start the mongo replica daemon on this single node. Depending on your distribution and how it’s configured, it’s probably something like this:

  # /etc/init.d/mongod start
  # mongo localhost
MongoDB shell version: 2.0.2
connecting to: localhost/test
  > use admin
switched to db admin
  > db.addUser("admin","password")

At this point, the admin datafiles should have been recreated. Check that the credentials work:

  > db.auth("admin","password")
1

If this returns the numeral “1”, then the login is successful. However, if this is a cluster, the node you’re on may have been marked as stale. To check and fix:

  > db.system.users.find()
error: { "$err" : "not master and slaveok=false", "code" : 13435 }
  > rs.slaveOk()
not master and slaveok=false

The rs.slaveOk() command will allow you to query normally from the secondary:

  SECONDARY> db.system.users.find()
{ "_id" : ObjectId("4fc4972525a7b704e9a3a09e"), "user" : "admin", "readOnly" : false, "pwd" : "2f1bffb1d28a2cca21679103652b1040" }

Now stop mongo, and repeat the above procedure on the other nodes:

  # /etc/init.d/mongod stop

When you have updated the admin password on all mongod replicas, restart all nodes in the replica set.

Now, you should find that all nodes have admin user accounts, and that you can use these to authenticate against each one.


Matt Parsons is a freelance Linux specialist who has designed, built and supported Unix and Linux systems in the finance, telecommunications and media industries.

He lives and works in London.