Configure MongoDB Cluster to Use TLS-SSL with Cluster Authentication and Mongodb Authentication on Linux

Introduction:

When a MongoDB HA cluster is created, it is configured to listen to external requests. This is mandatory as all nodes in the cluster should be able to sync with each other. While hosting such a configuration in a private dedicated network is secure, hosting it in an intranet or public network is not secure. In such cases, it is necessary to enable authentication on these clusters. Follow the steps outlined here to enable authentication on a MongoDB cluster and upgrade it to use SSL/TLS certificates.

As a prerequisite you need to have a working HA cluster. It can either be a replica set cluster or a sharding cluster:

Enable Mongodb Authentication:

Enable Role-Based Access Control

For encryption to be used in your replica set, first 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.


A DB user has to be first created in MongoDB, and this user can be later used in FileCloud for secure database access.
In this example, the user has the following details:

User NamePassword
dbuserpassw0rd1
OSCommand
Linux

$ use admin

$ db.createUser({user: 'dbuser', pwd: 'passw0rd1', roles:['root']})


Now to connect to MongoDB we issue the following command::

OSCommand
Linux

$ mongosh -u dbuser-p passw0rd1 --authenticationDatabase "admin"

Configuration of mongodb to use  TLS/SSL:

In order to use encryption, create certificates on all nodes and have a certification authority (CA) that signs them.

For testing purposes (to ensure encryption is working) you can use self-signed certificates; for a production environment, it's better to use valid certificates.

To proceed with certificate generation make sure you have OpenSSL installed on your system and that your certificates satisfy these requirements:

  • all certificates need to be signed by the same CA
  • the common name (CN) required during certificate creation must correspond to the hostname of the host
  • any other field requested in certificate creation should be a non-empty value and should reflect your organization details
  • all fields, except 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:

OSCommand
Linux

$ openssl genrsa -out mongoCA.key -aes256 8192

This creates a new 8192-bit private key and saves it in the file mongoCA.key, Remember to enter a strong passphrase when requested.

2 – Sign a new CA certificate

Now, create the “test” local certification authority that you’ll use later to sign each node certificate.

During certificate creation, values must be entered into some fields. You could choose these values randomly but it is better if they correspond to your organization’s details.

OSCommand
Linux

$ openssl req -x509 -new -extensions v3_ca -key mongoCA.key -days 365 -out mongoCA.crt

3 – Issue self-signed certificates for all nodes

For each node, generate a certificate request and sign it using the CA certificate created in the previous step.

Remember: Fill out all fields requested with the same values for each host, except fill out a different common name (CN) for each host -use a common name that corresponds to the particular hostname.

For the first node issue the following commands.

OSCommand
Linux

$ openssl req -new -nodes -newkey rsa:4096 -keyout mongossl1.key -out mongossl1.csr

$ openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -req -days 365 -in mongossl1.csr -out mongossl1.crt

$ cat mongossl1.key mongossl1.crt > psmdb1.pem

Apply the same for the second and third nodes.

4 - Create certificate for FileCloud web nodes

OSCommand
Linux

$ cat psmdb1.pem psmdb2.pem psmdb3.pem > filecloud-mongo.pem

5 – Place the files

You could execute all of the commands in the previous step on the same host, but instead copy the generated files to the proper nodes:

  • Copy to each node the CA certificate file: mongoCA.crt
  • Copy each self-signed certificate <hostname>.pem into the relative member
  • Create on each member a directory that only the MongoDB user can read, and copy both files there

    OSCommand
    Linux

    $ sudo mkdir -p /etc/mongodb/ssl
    $ sudo chmod 700 /etc/mongodb/ssl
    $ sudo chown -R mongod:mongod /etc/mongodb
    $ sudo cp mongossl1.pem /etc/mongodb/ssl
    $ sudo cp mongoCA.crt /etc/mongodb/ssl

  • Copy these files to all web nodes and make sure apache has access:

    /etc/ssl/filecloud-mongo.pem
    /etc/ssl/mongoCA.crt

6 – Configure mongod

Finally, inform mongod about the certificates to enable  encryption.

Change the configuration file /etc/mongod.conf on each host adding the following rows:

OSCommand
Linux

net:
    ssl:
       mode: requireSSL
       PEMKeyFile: /etc/mongodb/ssl/mongossl1.pem
       CAFile: /etc/mongodb/ssl/mongoCA.crt

      

Restart Mongod Daemon:

OSCommand
Linux

$ Systemctl restart mongod

Make sure to put the proper file names on other hosts (mongossl2.pem on mongossl2 hosts, and so on)

Now you should have a properly configured replica set that uses encrypted connections.

Issue the following command to connect on node mongossl1:

OSCommand
Linux

$ mongosh --authenticationDatabase "dbuser" --host mongossl1:27017 --ssl --sslCAFile /etc/ssl/mongoCA.crt --sslPEMKeyFile /etc/mongodb/ssl/mongossl1.pem -u dbuser -p passw0rd1

Certificate Notice :

For production use, your MongoDB deployment should use valid certificates generated and signed by a single certificate authority. You or your organization can generate and maintain an independent certificate authority, or use certificates generated by a third-party TLS/SSL vendor.
MongoDB can use any valid TLS/SSL certificate issued by a certificate authority or a self-signed certificate. If you use a self-signed certificate, although the communications channel is encrypted, there is no validation of server identity. Although such a situation prevents eavesdropping on the connection, it leaves you vulnerable to a man-in-the-middle attack. Using a certificate signed by a trusted certificate authority will permit MongoDB drivers to verify the server’s identity. In general, avoid using self-signed certificates unless the network is trusted.

Enable Cluster Node Authentication

To enable the cluster nodes to communicate with each other in a secure mode, enable what is called "Internal Authentication". This is done by using an x509 certificate or secure keyfile and configuring each cluster node to use that key.

1-Using x509 certificate:

You can use the same Pem file created for each node in the previous step for the cluster authentication between nodes, or you can generate another Pem file used for this purpose only.

MongoDB configuration should appear as follows:

OSCommand
Linux
net:
  ssl:
    mode: requireSSL
  PEMKeyFile: /etc/mongodb/ssl/mongossl1.pem
    CAFile: /etc/mongodb/ssl/mongoCA.crt
clusterFile: /etc/mongodb/ssl/mongossl1.pem
security
: authorization: enabled
clusterAuthMode: x509


Each node has its own PEMKeyFile and clusterFile.

Restart MongoDB server nodes.
Save the configuration changes and restart the server. Make sure the cluster is back to normal operation. 

2-Using Keyfile:

1- Create secure key
Create a secure key with the following command.

OSCommand
Linux$ sudo openssl rand -base64 741 > /etc/mongodb-keyfile $ sudo chmod 600 /etc/mongodb-keyfile
$ sudo chown mongodb.mongodb /etc/mongodb-keyfile


2- Copy secure key to all nodes
After the key is generated, copy the key file to all the cluster nodes.

3- Modify configuration file to use the key
Edit mongodb.conf file and make the following changes

OSCommand
Linux
net:
  ssl:
    mode: requireSSL
  PEMKeyFile: /etc/mongodb/ssl/mongossl1.pem
    CAFile: /etc/mongodb/ssl/mongoCA.crt
security
: keyFile: /etc/mongodb-keyfile


4-Restart MongoDB server nodes.

Save the configuration changes and restart the server. Make sure the cluster is back to normal operation. 

Configure Other DB URLs In Config File

Edit the configuration file WWWROOT/config/cloudconfig.php and update the following lines : 

Update DB URLs in cloudconfig.php
// ... Cloud Database
define("TONIDOCLOUD_DBSERVER", "mongodb://dbuser:passw0rd1@HOST1,HOST2,HOST3/?replicaSet=rs0&connectTimeoutMS=1000&ssl=true");
// ... Audit Database
define("TONIDOCLOUD_AUDIT_DBSERVER", "mongodb://dbuser:passw0rd1@HOST1,HOST2,HOST3/?replicaSet=rs0&connectTimeoutMS=1000&ssl=true");
// ... Settings Database
define("TONIDOCLOUD_SETTINGS_DBSERVER", "mongodb://dbuser:passw0rd1@HOST1,HOST2,HOST3/?replicaSet=rs0&connectTimeoutMS=1000&ssl=true");
// connection parameter for db backups:
define("AUTOBACKUP_MONGODUMP_PARAMS", "--host 'rs0/HOST1,HOST2,HOST3' --username dbuser --password passw0rd1 --authenticationDatabase admin --ssl --sslCAFile=/etc/ssl/mongoCA.crt --sslPEMKeyFile=/etc/ssl/filecloud-mongo.pem " );

Note: If the password you supply in AUTOBACKUP_MONGODUMP_PARAMS doesn't work or contains special characters,  the password parameter embedded in the characters \"password\"
For example:

define("AUTOBACKUP_MONGODUMP_PARAMS", "--host 'rs0/HOST1,HOST2,HOST3' --username dbuser --password \"passw0rd1?]\" --authenticationDatabase admin --ssl --sslCAFile=/etc/ssl/mongoCA.crt --sslPEMKeyFile=/etc/ssl/filecloud-mongo.pem " );



Add WWWROOT/config/cloudconfig.php at the bottom: 

Update DB URLs in cloudconfig.php
function
FC_MONGODB_URI_OPTIONS(){
    return [
        "tlsCertificateKeyFile" => "/etc/ssl/filecloud-mongo.pem",
        "tlsCAFile" => "/etc/ssl/mongoCA.crt"
    ];
}

and update the following line in WWWROOT/config/localstorage.php:

Update DB URLs in localstorageconfig.php
// ... Cloud Database
define("TONIDO_LOCALSTORAGE_DBSERVER", "mongodb://dbuser:passw0rd1@HOST1,HOST2,HOST3/?replicaSet=rs0&connectTimeoutMS=1000&ssl=true");

Restart Services

Finally, restart both MongoDB and Apache to get the security in-place.

Note

  • In case of any issues, disable security in mongodb and fix the problems.
  • To disable security, the mongodb security key has to be disabled and the database URLs have to be reverted back.