Understanding interprocess security in MongoDB

In the previous recipe, we saw how authentication can be enforced for a user to be logged in before allowing any operations on Mongo. In this recipe, we will look at interprocess security. By the term interprocess security, we don't mean encrypting the communication but only ensuring that the node, which is added to a replica set, is authenticated before being added to the replica set.

Getting ready

In this recipe, we will be starting multiple Mongo instances as part of a replica set. Thus, you might have to refer to the Starting multiple instances as part of a replica set recipe in Chapter 1, Installing and Starting the MongoDB Server, if you are not aware of how to start a replica set. Apart from that, in this recipe, all we will be looking at is how to generate a key file to be used, and the behavior when an unauthenticated node is added to the replica set.

How to do it…

To set the ground, we will be starting three instances, each listening to ports 27000, 27001, and 27002 respectively. The first two will be started by providing them with a path to the key file while the third will not receive this. Later, we will try adding these three instances to the same replica set. Let us take a look at the steps in detail:

  1. Let us generate the key file first. There is nothing spectacular about generating the key file. This is as simple as having a file with 6 to 1024 characters from the base64 character set. On the Linux filesystem, you may choose to generate pseudo random bytes using openssl, and encode them to base64. The following command will generate 500 random bytes, and these bytes will then be base64 encoded and written to keyfile:
    $ openssl rand –base64 500 > keyfile
    
  2. On a Unix filesystem, the key file should not have permissions for world and group, and thus, after it is created, we should execute the following command:
    $ chmod 400 keyfile
    
  3. Not giving write permission to the creator ensures that we don't overwrite the contents accidentally. On a Windows platform, however, openssl doesn't come out of the box and thus, you have to download it. The archive is extracted and the bin folder is added to the operating system's path variable. For Windows, we can download openssl from http://gnuwin32.sourceforge.net/packages/openssl.htm.
  4. You may even choose not to generate the key file using the approach mentioned earlier (that is, using openssl) and can take an easy way out by just typing plain text in the key file from any text editor of your choice. However, note that the characters , , and spaces are stripped off by Mongo and the remaining text is considered as the key. For example, we may create a file with the following content added to the key file. Again, the file will be named keyfile:
    somecontentaddedtothekeyfilefromtheeditorwithoutspaces

    Using any approach mentioned earlier, we would now have a keyfile in place that will be used for the next steps of the recipe

  5. We will now secure the Mongo processes by starting the Mongo instance as follows. I will be starting the Mongo instances on Windows; my key file ID named keyfile is placed on c:MongoDB, and the data paths are c:MongoDBdatac1, c:MongoDBdatac2, and c:MongoDBdatac3 respectively, for the three instances.
  6. Start the first instance listening to port 27000 as follows:
    C:> mongod --dbpath c:MongoDBdatac1 --port 27000 --auth --keyFile c:MongoDBkeyfile --replSet secureSet --smallfiles --oplogSize 100
    
  7. Similarly, start the second server listening to port 27001 as follows:
    C:> mongod --dbpath c:MongoDBdatac2 --port 27001 --auth --keyFile c:MongoDBkeyfile --replSet secureSet --smallfiles --oplogSize 100
    
  8. The third instance will be started, but without the --auth and --keyFile options, listening to port 27002 as follows:
    C:> mongod --dbpath c:MongoDBdatac3 --port 27002 --replSet secureSet --smallfiles --oplogSize 100
    
  9. We then start a Mongo shell and connect it to port 27000, which is the first instance started. From the Mongo shell, we type the following command:
    > rs.initiate()
    
  10. In a few seconds, the replica set will be initiated with just one instance in it. We will now try to add two new instances to this replica set. First, the one listening on port 27001, as follows (you will need to add the appropriate hostname; Amol-PC is the hostname in my case):
    > rs.add({_id:1, host:'Amol-PC:27001'})
    
  11. We will then execute the following command to confirm the status of the newly added instance, by executing rs.status(). It should soon come up as a secondary.
  12. We will now finally try and add an instance that was started without the --auth and --keyFile options, as follows:
    > rs.add({_id:2, host:'Amol-PC:27002'})
    
  13. This should add the instance to the replica set, but executing rs.status() will show the status of the instance as UNKNOWN. The server logs for the instance running on 27002 should show some authentication errors as well.
  14. We will finally have to restart this instance. However, this time we provide the --auth and --keyFile options as follows:
    C:> mongod --dbpath c:MongoDBdatac3 --port 27002 --replSet secureSet --smallfiles --oplogSize 100 --auth --keyFile c:MongoDBkeyfile
    
  15. Once the server is started, connect to it from the shell again and type in rs.status(). In a few moments, it should come up as a secondary instance.

There's more…

In this recipe, we explored interprocess security to prevent unauthenticated nodes from being added to the mongo replica set. We still haven't encrypted the data that is being sent over the wire to ensure it's delivered securely. In Appendix, Concepts for Reference, we will see how to build the MongoDB server from the source and how to enable encryption of the contents over the wire.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset