§2023-07-27

-Deploy a 3-Node MongoDB 4.0 Replica Set with X.509 Authentication


  1. Server used
Machine IP OS mongod Version Replication Set momgosh Avialbale Saharding
hc4Jammy.yushei.com.tw:2701 192.168.2.195 odroid-hc4 Ubuntu Jammy 7.0.0-rc8 odroid01 Yes No
N2Jammy.yushei.com.tw:27017 192.168.2.177 odroid-n2+ Ubuntu Jammy 7.0.0-rc8 odroid01 No No
x8664Arch.yushei.com.tw:27017 192.168.2.132 AMD x86_64 ArchLinux 7.0.0-rc8 odroid01 Yes No
orgpi5Arch.yushei.net:27017 192.168.48.241 Orange Pi 5 Plus, 16G mem, PCIeSSD 256G Archlinux 7.0.0-rc8 N/A Yes No
orgpi5Jammy.yushei.net 192.168.48.247 Orange Pi 5 Plus, 8G mem, PCIeSSD 256G Ubuntu Jammy 7.0.0-rc8 N/A Yes No
hc4Jammy.yushei.net 192.168.48.243 Odroid-hc4 Ubuntu Jammy 7.0.0-rc8 N/A Yes No
h2Jammy.yushei.net 192.168.11.248/

n2Mnjaro.yushei.net. 7200 IN A 192.168.48.245

  1. Generating the X.509 Certificates

An X.509 certificate needs to be generated for each of our nodes. You will act as the CA so we will sign them ourselves. To do this we firstly create a private key, issue a CA certificate and thereafter issue 3 more certificates for each MongoDB node.

@hc4Mnjaro-01.yushei.net

2.1 Create Certificate Authority

$ pwd
/opt/xfs/home/alexlai
$ mkdir openssl && cd openssl

# Execute the following openssl command to create the rootCA.keyand rootCA.crt

$ openssl req -x509 \
            -sha256 -days 395 \
            -nodes \
            -newkey rsa:2048 \
            -subj "/CN=hc4Mnjaro-01.yushei.net/C=TW/L=Taiching Taiwan" \
            -keyout rootCA.key -out rootCA.crt 
$ ls -al
total 12
drwxr-xr-x  2 alexlai alexlai   42 Jan  9 15:30 .
drwx------ 10 alexlai alexlai 4096 Jan  9 15:27 ..
-rw-r--r--  1 alexlai alexlai 1257 Jan  9 15:30 rootCA.crt
-rw-------  1 alexlai alexlai 1704 Jan  9 15:30 rootCA.key

2.2

Important Note: All 3 certificate details have to be identical, apart from the host name. This is the reason hardcoding an automated script is a more preferred and quicker way of generating our certificates.

#!/bin/bash

if [ "$1" = "" ]; then
echo 'Please enter your hostname (CN):'
exit 1
fi

HOST_NAME="$1"
SUBJECT="/C=Tw/ST=Taiwan/L=Taichung/O=yushei.net/OU=ComputerDepartment/CN=$HOST_NAME"

# certificate valid for 365 days + 30 days
openssl req -new -nodes -newkey rsa:4096 -subj "$SUBJECT" -keyout $HOST_NAME.key -out $HOST_NAME.csr
openssl x509 -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -req -days 395 -in $HOST_NAME.csr -out $HOST_NAME.crt
rm $HOST_NAME.csr
cat $HOST_NAME.key $HOST_NAME.crt > $HOST_NAME.pem
rm $HOST_NAME.key
rm $HOST_NAME.crt

2.2.1 $ ./genCertificate.sh hc4Jammy

$ ./genCertificate.sh hc4Jammy
Certificate request self-signature ok
subject=C = Tw, ST = Taiwan, L = Taichung, O = yushei.net, OU = ComputerDepartment, CN = hc4Jammy

$ ./genCertificate.sh n2Mnjaro
Certificate request self-signature ok
subject=C = Tw, ST = Taiwan, L = Taichung, O = yushei.net, OU = ComputerDepartment, CN = n2Mnjaro

$ ./genCertificate.sh hc4Mnjaro-01
Certificate request self-signature ok
subject=C = Tw, ST = Taiwan, L = Taichung, O = yushei.net, OU = ComputerDepartment, CN = hc4Mnjaro-01

$ ./genCertificate.sh hc4Mnjaro-01.yushei.net
Certificate request self-signature ok
subject=C = Tw, ST = Taiwan, L = Taichung, O = yushei.net, OU = ComputerDepartment, CN = hc4Mnjaro-01.yushei.net

$ ls -al
total 44
drwxr-xr-x  2 alexlai alexlai  149 Jan  9 15:42 .
drwx------ 10 alexlai alexlai 4096 Jan  9 15:27 ..
-rwxr-xr-x  1 alexlai alexlai  510 Jan  9 15:40 genCertificate.sh
-rw-r--r--  1 alexlai alexlai 4813 Jan  9 15:42 hc4Jammy.pem
-rw-r--r--  1 alexlai alexlai 4817 Jan  9 15:40 hc4Mnjaro-01.pem
-rw-r--r--  1 alexlai alexlai 4813 Jan  9 15:41 n2Mnjaro.pem
-rw-r--r--  1 alexlai alexlai 1257 Jan  9 15:30 rootCA.crt
-rw-------  1 alexlai alexlai 1704 Jan  9 15:30 rootCA.key
-rw-r--r--  1 alexlai alexlai   41 Jan  9 15:42 rootCA.srl
  1. Now, move hc4jammy.pem, n2Mnjaro.pem and hc4MnJaro-01.pem and rootCA.crt to an appropriate directory and configure the appropriate permissions and ownership. for example @hc4Mnjaro-01.yushei.net
#create ssl directory in mongodb folder
$ sudo mkdir -p /etc/mongodb/ssl

#move hc4Mnjaro01.pem and copy rootCA.crt into it
$ sudo cp -v  hc4Mnjaro-01.pem /etc/mongodb/ssl/ 
$ sudo cp -v rootCA.crt /etc/mongodb/ssl/

#chmod to 700 and change permissions of the folder to mongo.
$ sudo chmod 700 /etc/mongodb/ssl  
$ sudo chown -R mongodb:mongodb /etc/mongodb

$ sudo ls -al /etc/mongodb/ssl
total 20
drwx------ 2 mongodb mongodb 4096 Jan  9 16:00 .
drwxr-xr-x 3 mongodb mongodb 4096 Jan  9 16:00 ..
-rw-r--r-- 1 mongodb mongodb 4821 Jan  9 16:00 hc4Mnjaro-01.pem
-rw-r--r-- 1 mongodb mongodb 1257 Jan  9 16:00 rootCA.crt
  1. Configuring MongoDB for a X.509 Authentication replica set
# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /opt/xfs/mongoDB/log/mongod.log

# Where and how to store data.
storage:
  dbPath: /opt/xfs/mongoDB/data
  journal:
    enabled: true

  engine:  wiredTiger
#  mmapv1:
#  wiredTiger:

# how the process runs
# processManagement:
#  fork: true  # fork and run in background
#  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 27017
  # bindIp: ysubutun.chingyen.com.tw
  bindIpAll: true   # default is Flase, and mutual exclusive with bindIP.
  # MongoDB 4.2 deprecates ssl options in favor of tls options with identical functionality
  # ssl param is inside net:
  # ssl: 
  # ssl:
        # mode: preferSSL
        # PEMKeyFile: /etc/mongodb/ssl/hc4Mnjaro-01.pem
        # CAFile: /etc/mongodb/ssl/rootCA.crt
        # clusterFile: /etc/mongodb/ssl/hc4Mnjaro-01.pem
        # PEMKeyPassword: <your-ssl-passphrase>
        # clusterPassword: <your-ssl-passphrase>
  tls:
      mode: requireTLS
      certificateKeyFile: /etc/mongodb/ssl/hc4Mnjaro-01.yushei.net.pem
      CAFile: /etc/mongodb/ssl/rootCA.crt

# security
security:
    authorization: enabled
    clusterAuthMode: x509

#operationProfiling:


# replicationSet
# replication:
#  replSetName: AlexLaiHome

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

¶mongosh

$ ./mongosh --tls --host hc4Mnjaro-01.yushei.net   --tlsCertificateKeyFile hc4Mnjaro-01.yushei.net.pem --tlsCAFile rootCA.crt 
Current Mongosh Log ID: 63bc10f507084bc794d31d74
Connecting to:          mongodb://hc4Mnjaro-01.yushei.net:27017/?directConnection=true&tls=true&tlsCertificateKeyFile=hc4Mnjaro-01.yushei.net.pem&tlsCAFile=rootCA.crt&appName=mongosh+1.6.1
Using MongoDB:          6.0.3
Using Mongosh:          1.6.1

For mongosh info see: https://docs.mongodb.com/mongodb-shell/

Warning: Found ~/.mongorc.js, but not ~/.mongoshrc.js. ~/.mongorc.js will not be loaded.
  You may want to copy or rename ~/.mongorc.js to ~/.mongoshrc.js.
test> show dbs
MongoServerError: command listDatabases requires authentication