In this third and final post of the series, we look at how to configure transport encryption on a deployed MongoDB replica set. Security vulnerabilities can arise when internal personnel have legitimate access to the private network, but should not have access to the data. Encrypting intra-node traffic ensures that no one can “sniff” sensitive data on the network.
In part 1 we described MongoDB replica sets and how they work.
In part 2 we provided a step-by-step guide to deploy a simple 3-node replica set, including information on replica set configuration.
In order for the encryption to be used in our replica set, we need first to activate Role-Based Access Control (RBAC). By default, a MongoDB installation permits anyone to connect and see the data, as in the sample deployment we created in part 2. Having RBAC enabled is mandatory for encryption.
RBAC governs access to a MongoDB system. Users are created and assigned privileges to access specific resources, such as databases and collections. Likewise, for carrying out administrative tasks, users need to be created with specific grants. Once activated, every user must authenticate themselves in order to access MongoDB.
Prior to activating RBAC, let’s create an administrative user. We’ll connect to the PRIMARY member and do the following:
|
1 |
rs-test:PRIMARY> use admin<br>switched to db admin<br>rs-test:PRIMARY> db.createUser({user: 'admin', pwd: 'secret', roles:['root']})<br>Successfully added user: { "user" : "admin", "roles" : [ "root" ] } |
Let’s activate the RBAC in the configuration file /etc/mongod.conf on each node
|
1 |
security:<br> authorization: enabled |
and restart the daemon
|
1 |
sudo service mongod restart |
Now to connect to MongoDB we issue the following command:
|
1 |
mongo -u admin -p secret --authenticationDatabase "admin" |
MongoDB supports X.509 certificate authentication for use with a secure TLS/SSL connection. The members can use X.509 certificates to verify their membership of the replica set.
In order to use encryption, we need to create certificates on all the nodes and have a certification authority (CA) that signs them. Since having a certification authority can be quite costly, we decide to use self-signed certificates. For our purposes, this solution ensures encryption and has no cost. Using a public CA is not necessary inside a private infrastructure.
To proceed with certificate generation we need to have openssl installed on our system and certificates need to satisfy these requirements:
The following guide describes all the steps to configure internal X.509 certificate-based encryption.
|
1 |
openssl genrsa -out mongoCA.key -aes256 8192<br> |
We have created a new 8192 bit private key and saved it in the file mongoCA.key
Remember to enter a strong passphrase when requested.
Now we are going to create our “fake” local certification authority that we’ll use later to sign each node certificate.
During certificate creation, some fields must be filled out. We could choose these randomly but they should correspond to our organization’s details.
|
1 |
root@psmdb1:~# openssl req -x509 -new -extensions v3_ca -key mongoCA.key -days 365 -out<br> mongoCA.crt<br> Enter pass phrase for mongoCA.key:<br> You are about to be asked to enter information that will be incorporated<br> into your certificate request.<br> What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank<br> For some fields there will be a default value,<br> If you enter '.', the field will be left blank.<br> -----<br> Country Name (2 letter code) [AU]:US<br> State or Province Name (full name) [Some-State]:California<br> Locality Name (eg, city) []:San Francisco<br> Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Ltd<br> Organizational Unit Name (eg, section) []:DBA<br> Common Name (e.g. server FQDN or YOUR name) []:psmdb<br> Email Address []:[email protected] |
For each node, we need to generate a certificate request and sign it using the CA certificate we created in the previous step.
Remember: fill out all the fields requested the same for each host, but remember to fill out a different common name (CN) that must correspond to the hostname.
For the first node issue the following commands.
|
1 |
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb1.key -out psmdb1.csr<br><br>openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb1.csr -out psmdb1.crt<br><br>cat psmdb1.key psmdb1.crt > psmdb1.pem<br> |
for the second node
|
1 |
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb2.key -out psmdb2.csr <br><br>openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb2.csr -out psmdb2.crt <br><br>cat psmdb2.key psmdb2.crt > psmdb2.pem |
and for the third node
|
1 |
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb3.key -out psmdb3.csr <br><br>openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb3.csr -out psmdb3.crt <br><br>cat psmdb3.key psmdb3.crt > psmdb3.pem |
We could execute all of the commands in the previous step on the same host, but now we need to copy the generated files to the proper nodes:
|
1 |
sudo mkdir -p /etc/mongodb/ssl<br>sudo chmod 700 /etc/mongodb/ssl<br>sudo chown -R mongod:mongod /etc/mongodb<br>sudo cp psmdb1.pem /etc/mongodb/ssl<br>sudo cp mongoCA.crt /etc/mongodb/ssl |
Do the same on each host.
Finally, we need to instruct mongod about the certificates to enable the encryption.
Change the configuration file /etc/mongod.conf on each host adding the following rows:
|
1 |
net:<br> port: 27017<br> ssl:<br> mode: requireSSL<br> PEMKeyFile: /etc/mongodb/ssl/psmdb1.pem<br> CAFile: /etc/mongodb/ssl/mongoCA.crt<br> clusterFile: /etc/mongodb/ssl/psmdb1.pem<br> security:<br> authorization: enabled<br> clusterAuthMode: x509 |
Restart the daemon
|
1 |
sudo service mongodb restart |
Make sure to put the proper file names on each host (psmdb2.pem on psmdb2 host and so on)
Now, as long as we have made no mistakes, we have a properly configured replica set that is using encrypted connections.
Issue the following command to connect on node psmdb1:
|
1 |
mongo admin --ssl --sslCAFile /etc/mongodb/ssl/mongoCA.crt <br>--sslPEMKeyFile /etc/mongodb/ssl/psmdb1.pem <br>-u admin -p secret --host psmdb1 |
Resources
RELATED POSTS