Issue: Unable to Connect to MongoDB with TLS and Authentication
MongoDB Setup:
I’m running MongoDB on a Docker container, and I’ve enabled TLS/SSL and role-based access control (RBAC) with internal authentication. Here’s an outline of my setup:
MongoDB Version: 6.x (Running in Docker)
mongod.conf Configuration:
net:
port: 27017
bindIp: 0.0.0.0
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongo.pem # Combined certificate and private key
CAFile: /etc/ssl/ca.pem # Certificate Authority file
allowConnectionsWithoutCertificates: false
security:
authorization: "enabled" # Enabling Role-Based Access Control (RBAC)
keyFile: /etc/rs_keyfile # Path to key file for replica set authentication
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
verbosity: 2
Certificates:
mongo.pem: Contains the server certificate and private key.
ca.pem: Contains the CA certificate that signed mongo.pem.
Docker Compose:
MongoDB is running in a Docker container, and I have generated the required PEM files using openssl.
How I Start MongoDB:
I start MongoDB with the above configuration using Docker. Everything seems to start correctly, but when I try to connect to MongoDB using mongosh with TLS, I encounter connection issues.
Error When Connecting:
I attempt to connect using the following command:
mongosh --tls --tlsCAFile /etc/ssl/ca.pem --tlsCertificateKeyFile /etc/ssl/mongo.pem --host 127.0.0.1 --port 27017
However, I get the following error:
MongoServerSelectionError: connection to 127.0.0.1:27017 closed
When using tlsAllowInvalidHostnames
, I still can’t establish a successful connection.
Additional Information:
I confirmed the certificates using openssl
verify and openssl s_client
, and they seem valid.
Error in Log Files:
I noticed the following errors in the MongoDB logs:
User assertion "NotYetInitialized: no replset config has been received"
Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [local.oplog.rs] not found.
Questions: Certificate Setup: Is there any issue with how I’ve generated or configured the certificates for MongoDB?
Hostname Issue: How can I properly resolve the “hostname mismatch” issue for local connections when using TLS?
Replica Set Configuration: Even though I haven’t enabled replication, I still see replica set errors. Could this be related to the issue?
Here is the output of openssl x509 -in /etc/ssl/mongo.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 23:e7:a5:54:fa:d1:5f:12:7c:a7:5a:16:7c:63:50:23:16:39:a2:c9
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = UH, L = GO, O = NFA, OU = NFA, CN = NFA, emailAddress = [email protected]
Validity Not Before: Sep 14 15:11:18 2024 GMT
Not After : Sep 14 15:11:18 2025 GMT Subject: CN = mongo1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption Public-Key: (2048 bit)
00:c5:46:e0:4f:f2:3c:14:0e:67:6c:e6:ee:60:37:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: Key Encipherment, Data Encipherment
X509v3 Extended Key Usage: TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:mongo1, IP Address:127.0.0.1, IP Address:0.0.0.0
X509v3 Subject Key Identifier: F1:EC:87:9E:4B:1C:5B:44:EA:91:68:45:2F:F3:20:44:B0:4D:22:69
X509v3 Authority Key Identifier: 17:40:89:67:A8:59:00:18:A4:E4:33:BD:F2:7A:2D:D0:16:C7:D2:78
Signature Algorithm: sha256WithRSAEncryption
2
Answers
I’m now able to connect using TLS with the admin user, but when I try to initialize the replica set, I encounter the following error:
MongoServerError[NodeNotFound]: replSetInitiate quorum check failed because not all proposed set members responded affirmatively: localhost:27018 failed with Error connecting to localhost:27018 (127.0.0.1:27018) :: caused by :: onInvoke :: caused by :: Connection refused, localhost:27019 failed with Error connecting to localhost:27019 (127.0.0.1:27019) :: caused by :: onInvoke :: caused by :: Connection refused
I want to make sure I’m following all the necessary steps, especially around generating certificates.Here’s my process:
openssl.cnf:
Steps for certificate generation:
Generate the CA certificate:
openssl req -newkey rsa:2048 -new -x509 -days 3650 -nodes -config openssl.cnf -out ca.crt -keyout ca.key
2.Combine the CA key and certificate
3.Generate a member certificate:
4.Combine the member key and certificate:
Next, I generate the replica set keyfile:
Then in mongod.conf:
I tried to initiate the rs with machine ip (also added to openssl) / localhost / mongo network. What might I be doing wrong?
Mit comment was a bit misleading. Of course, you can "use" a MongoDB without initiated the Replica Set. But as long as you did not initiate the Replica Set, it acts as a stand-alone MongoDB.
I am not familiar with Docker, I don’t know how it initiate the replia set. But you should find several answers here on SO with search function.
Let’s focus on your certificate issue:
As said, I have no clue about Docker, certainly
is (at least) a security risk.
IP Address:127.0.0.1, IP Address:0.0.0.0
makes the certificate valid for any host.First part:
You created a server certificate:
Client certificates are not used (where I don’t see any issue, because client certificates add only negligible security, unless they are used for x.509 authentication)
Thus your config should be
And connection is done like this:
Maybe, due to Docker and certificate you have to use real hostname instead of
--host 127.0.0.1
or use option--allowInvalidHostnames
.It works like this: The
mongod
server provides the server certificate/etc/ssl/mongo.pem
and themongosh
client verifies this certificate with/etc/ssl/ca.pem
. The server does not receive any client certificate, thusnet.tls.CAFile
is not needed.Second part:
From your question, it is not clear whether you like to use client certificates or not. If yes, then first you need to create the client certificate (assuming
/etc/ssl/client.pem
), i.e. certificate option must beMost likely it will be also issued by certificate
/etc/ssl/ca.pem
. In this case configuration and connection would be like this:Some notes:
X509v3 Subject Alternative Name
is not relevant in client certificate, it is not used.You could create a single certificate with both options,
TLS Web Client Authentication
andTLS Web Server Authentication
. But I in my opinion, this is rather pointless, because you don’t gain anything for the client certificate part. Unless you use the client certificate for x.509 authentication it is also accepted when invalid. Hostnames in client certificate are not verified at all.