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 managekeystores
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:
- use the mongo-mounts configuration option to restrict the resources exposed by RESTHeart;
- 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.