Secure connection to MongoDB

Introduction

This section provides instructions on how to secure the connection between RESTHeart and MongoDB by enabling the MongoDB authentication, connect the two processes over TLS and restrict the permissions of the MongoDB user used by RESTHeart.

Enable MongoDB authentication

This section assumes using MongoDB 3.2 or later. For other versions, the security configuration is similar but different. Refer to the MongoDB documentation for more information.

Start MongoDB with authentication and connect to the MongoDB instance from a client running on the same system. This access is made possible by the localhost exception. Again, you might prefer to run the MongoDB process in background, using the --fork parameter.

$ mongod --fork --syslog --auth
$ mongo

In this section we will use the MongoDB superuser role root that provides access to the all operations and all the resources.

However the best practice is to use a MongoDB user with restricted access. For instance, it could be restricted to use only a single DB in read only mode. For more information refer to MongoDB authentication with just enough permissionssection.

Create the admin user. The procedure is different depending on MongoDB version.

> use admin
> db.createUser({
    user: "admin",
    pwd: "changeit",
    roles:[ "root" ]
})
We need to provide the MongoDB user authentication credentials in the RESTHeart configuration file.

We’ll define a restheart.yml configuration file.

Fist create a configuration file with default values with:

$ java restheart.jar -t 2> ./etc/restheart.yml

Open the file ./etc/restheart.yml with an editor, Find and modify the following section providing the user-name, password and authentication db (the db where the MongoDB user is defined, in our case ‘admin’).

mongo-uri: mongodb://admin:changeit@127.0.0.1/?authSource=admin

Now start RESTHeart specifying the configuration file:

$ java -jar restheart.jar etc/restheart.yml

Test the connection open http://localhost:8080/roles/admin

Connect to MongoDB over TLS

MongoDB clients can use TLS/SSL to encrypt connections to mongod and mongos instances.

To configure RESTHeart for TLS/SSL do as follows:

  • create the keystore importing the public certificate used by mongod using keytool (keytool is the java tool to manage keystores of cryptographic keys)
$ keytool -importcert -file mongo.cer -alias mongoCert -keystore rhTrustStore

# asks for password, use "changeit"
  • specify the ssl option in the mongo-uri in the restheart yml configuration file:
mongo-uri: mongodb://your.mongo-domain.com?ssl=true
  • start restheart with following options:
$ java -Dfile.encoding=UTF-8 -server -Djavax.net.ssl.trustStore=rhTrustStore -Djavax.net.ssl.trustStorePassword=changeit -Djavax.security.auth.useSubjectCredsOnly=false -jar restheart.jar etc/restheart.yml

Restrict permissions of MongoDB user

In the previous examples we used a MongoDB user with root role for the sake of simplicity. This allows RESTHeart to execute any command on any MongoDB resource.

On production environments a strong security isolation is mandatory.

In order to achieve it, the best practice is:

  1. use the mongo-mounts configuration option to restrict the resources exposed by RESTHeart;
  2. use a MongoDB user with just enough permission: read or readWrite on mounted databases

The following example, creates a MongoDB user with appropriate roles to expose the databases *restheart.

> use admin
> db.createUser({user: "restheart",
    pwd: <password>,
    roles: [{role: "readWrite", db: "restheart"},
            {role: "clusterMonitor", db: "admin"}
]})

The built-in role clusterMonitor is needed to check the replica set status of MongoDB.

To list the databases (i.e. GET /, the root resource) the listDatabases permission is needed. This permission is granted by the readWriteAnyDatabase role or you can create a custom role.

To allow deleting a database the dropDatabase permission is needed. This permission is granted by the dbAdmin role or you can create a custom role.