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.
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 Core configuration file: see docs.
We’ll use the restheart.yml
configuration file that comes with RESTHeart download package (you find it in the etc directory)
$ vi etc/restheart.yml
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 Core specifying the configuration file:
$ java -jar restheart.jar etc/restheart.yml -e etc/default.properties
Test the connection open http://localhost:8080/roles/admin
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 Core 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 Core;
- 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.
Connect to MongoDB over TLS/SSL
In case MongoDB uses a public TLS/SSL certificate there is nothing to configure on RESTHeart, except for the proper Connection String URI Format.
To configure RESTHeart for using instead a private TLS/SSL certificate (read What’s the Difference Between a Public and Private Trust Certificate?) do as follows:
- create the keystore importing the certificate used by
mongod
usingkeytool
(withkeytool
, 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 -e etc/default.properties
References from MongoDB docs: