
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.
Enable Role-Based Access Control
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:
rs-test:PRIMARY> use admin
switched to db admin
rs-test:PRIMARY> db.createUser({user: 'admin', pwd: 'secret', roles:['root']})
Successfully added user: { "user" : "admin", "roles" : [ "root" ] }
Let’s activate the RBAC in the configuration file /etc/mongod.conf on each node
security:
authorization: enabled
and restart the daemon
sudo service mongod restart
Now to connect to MongoDB we issue the following command:
mongo -u admin -p secret --authenticationDatabase "admin"
Certificates
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:
- any certificate needs to be signed by the same CA
- the common name (CN) required during the certificate creation must correspond to the hostname of the host
- any other field requested in the certificate creation should be a non-empty value and, hopefully, should reflect our organization details
- it is also very important that all the fields, except the CN, should match those from the certificates for the other cluster members
The following guide describes all the steps to configure internal X.509 certificate-based encryption.
1 – Connect to one of the hosts and generate a new private key using openssl
openssl genrsa -out mongoCA.key -aes256 8192
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.
2 – Sign a new CA certificate
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.
root@psmdb1:~# openssl req -x509 -new -extensions v3_ca -key mongoCA.key -days 365 -out
mongoCA.crt
Enter pass phrase for mongoCA.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
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
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:San Francisco
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Ltd
Organizational Unit Name (eg, section) []:DBA
Common Name (e.g. server FQDN or YOUR name) []:psmdb
Email Address []:corrado@mycompany.com
3 – Issue self-signed certificates for all the nodes
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.
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb1.key -out psmdb1.csr
openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb1.csr -out psmdb1.crt
cat psmdb1.key psmdb1.crt > psmdb1.pem
for the second node
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb2.key -out psmdb2.csr
openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb2.csr -out psmdb2.crt
cat psmdb2.key psmdb2.crt > psmdb2.pem
and for the third node
openssl req -new -nodes -newkey rsa:4096 -keyout psmdb3.key -out psmdb3.csr
openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in psmdb3.csr -out psmdb3.crt
cat psmdb3.key psmdb3.crt > psmdb3.pem
4 – Place the files
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:
- Copy to each node the CA certifcate file: mongoCA.crt
- Copy each self signed certifcate <hostname>.pem into the relative member
- Create on each member a directory that only the MongoDB user can read, and copy both files there
sudo mkdir -p /etc/mongodb/ssl
sudo chmod 700 /etc/mongodb/ssl
sudo chown -R mongod:mongod /etc/mongodb
sudo cp psmdb1.pem /etc/mongodb/ssl
sudo cp mongoCA.crt /etc/mongodb/ssl
Do the same on each host.
5 – Configure mongod
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:
net:
port: 27017
ssl:
mode: requireSSL
PEMKeyFile: /etc/mongodb/ssl/psmdb1.pem
CAFile: /etc/mongodb/ssl/mongoCA.crt
clusterFile: /etc/mongodb/ssl/psmdb1.pem
security:
authorization: enabled
clusterAuthMode: x509
Restart the daemon
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:
mongo admin --ssl --sslCAFile /etc/mongodb/ssl/mongoCA.crt
--sslPEMKeyFile /etc/mongodb/ssl/psmdb1.pem
-u admin -p secret --host psmdb1
Access the first two articles in this series
- Part 1: Introduces basic replica set concepts, how it works and what its main features
- Part 2: Provides a step-by-step guide to configure a three-node replica set
The post MongoDB: deploy a replica set with transport encryption (part 3/3) appeared first on Percona Database Performance Blog.