5

I Read through many documents in the mongoDB doc, still unclear how authentication works for clients an member of replica set(using x.509).

Found a resource "http://pe-kay.blogspot.in/2016/02/securing-mongodb-using-x509-certificate.html" which was well documented, still not clear as how authentication happens.

Considering the below mongoConfig and commands for starting server and mongo client:-

mongoConfig.cfg

storage:
    dbPath: "../DB"
  security:
    clusterAuthMode: x509
  net:
    port: 27001
  ssl:
    mode: "requireSSL"
    PEMKeyFile: "../server/security/one.pem"
    clusterFile: "../server/security/one.pem"
    CAFile: "../server/security/rootCA.crt"

Commands in Prompt:-

cPrompt> mongod -v --config "../custom/mongoConf.cfg" --replSet "one"

cPrompt> mongo -ssl --sslPEMKeyFile "../client/security/oneHost.pem" --sslCAFile "../client/security/rootCA.crt" --host mylocalhost --port 27001

1) Is it a oneWay or a twoWay SSL/TLS ?

2) How authentication between members of replicaSet takes place (mongod - mongod while doing replication) and between server-client (mongod-mongo say mongoShell or application) ?

3) Which version of TLS is used ?

Can someone explain in detail ?

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
Sandeep
  • 51
  • 4

1 Answers1

4

This is an old question, however I was facing the same issues and it took me a lot of time to get it working. Some items are rather essential but quite hidden in the documentation.

I try to give an overview without doing simple copy/paste from the MongoDB documentation.

In general a x.509 certificate in MongoDB provides these functions:

  • Generate keys to encrypt the connection
  • Ensure the connection is established from correct host (i.e. the declared hostname matches the actual hostname)
  • Authenticate a client (instead of using username + password or keyfile)

As starting point, one should have a look at these tutorials:

TLS/SSL settings are defined in this configuration file section:

net:
   tls:
      certificateKeyFile: server.pem
      CAFile: server-ca.crt
      clusterFile: member.pem
      clusterCAFile: cluster-ca.crt

They correspond to command line options

  • --tlsCertificateKeyFile server.pem
  • --tlsCAFile server-ca.crt
  • --tlsClusterFile member.pem
  • --tlsClusterCAFile cluster-ca.crt

All other TLS/SSL related parameters are well documented and usually they should not cause any confusion or misunderstanding.

Step 1

When a client tries to establish a TLS/SSL enabled connection, then the mongod/mongos server presents a server certificate. The client verifies this certificate with a CA.

  • A client can be a normal client (e.g. the Mongo shell mongosh) or an internal Replica Set / Sharded Cluster member

  • The server certificate is always the same, mongod/mongos does not distinct the client types

  • The server certificate is defined by parameter

    net.tls.certificateKeyFile or --tlsCertificateKeyFile

  • A normal client can verify the server certificate for example with these:

    • Option --tls --tlsCAFile server-ca.cer

    • Option --tls --tlsUseSystemCA

    • Connection string parameter tls=true&tlsCAFile=server-ca.cer

    • --tlsUseSystemCA exists only as option, you cannot define it in connection string. Would be like this:

      mongosh --tlsUseSystemCA "mongodb://localhost/?tls=true"

  • An internal Replica Set / Sharded Cluster member verifies the server certificate by parameter

    net.tls.CAFile or --tlsCAFile

  • If net.tls.CAFile or --tlsCAFile is not specified and you are not using x.509 authentication, the system-wide CA certificate store will be used. If you use x.509 authentication, then net.tls.CAFile or --tlsCAFile is required.

Step 2

The client presents a client certificate to the mongod/mongos server. The client certificate can be used to authenticate the user. In this case, you don't have to provide a password/keyfile.

  • For normal client, x.509 authentication is enabled by user creation, e.g. db.getSiblingDB("$external").runCommand({createUser: "CN=myName,OU=myOrgUnit,O=myOrg,..."})
  • For Replica Set / Sharded Cluster member, x.509 authentication is enabled by parameter security.clusterAuthMode: x509

A normal client (e.g. mongosh) provides client certificate for example by these parameters:

  • mongosh --tls --tlsCertificateKeyFile client.pem (no x.509 authentication)
  • mongosh --tls --authenticationDatabase $external --authenticationMechanism MONGODB-X509 --tlsCertificateKeyFile client.pem (with x.509 authentication)
  • mongosh "mongodb://username:secret@localhost/?tls=true&authSource=admin&tlsCertificateKeyFile=client.pem" (no x.509 authentication)
  • mongosh "mongodb://localhost/?tls=true&authSource=$exernal&tlsCertificateKeyFile=client.pem&authMechanism=MONGODB-X509" (with x.509 authentication)

An internal Replica Set / Sharded Cluster member provides member certificate by parameter net.tls.clusterFile or --tlsClusterFile

  • The monogd/mongos sever verifies the client/member certificate with Root-CA defined by parameter net.tls.clusterCAFile or --tlsClusterCAFile
  • The client can be a normal client (e.g. the Mongo shell mongosh) or an internal Replica Set / Sharded Cluster member
  • The Root-CA is always the same, mongos/mongod does not distinct between client certificate and member certificate
  • If net.tls.clusterCAFile or --tlsClusterCAFile is not defined, then net.tls.CAFile/--tlsCAFile is used for verification.

Pitfalls:

  • Some Mongo documents just refer to "client" certificate/connection. Be aware, this means normal clients (e.g. mongosh) as well as internal Replica Set / Sharded Cluster member clients. In this answer I use terms "client certificate" and "member certificate" for better understanding.
  • Server certificates and Member certificates must have the same O, OU, and DC in their subject name
  • Client certificates and Member certificates must have different O, OU, and DC in their subject name
  • Parameter pairs certificateKeyFile/CAFile and clusterFile/clusterCAFile are not used to separate connections from normal clients and connections from Replica Set / Sharded Cluster members. They are used to separate client and server certificates, i.e. incoming and outgoing connections. In my opinion, these names are totally miss-leading.
  • You can use a common Root-CA, defined by net.tls.CAFile
  • You can also use the same certificate for client, member and server. This common certificate can be even used for x.509 authentication of Replica Set / Sharded Cluster members. This certificate only provides encrypted connection and x.509 member authentication. Of course, you cannot use it for x.509 authentication of normal clients.
  • Option tlsAllowInvalidCertificates has no effect on x509 authentication. For x509 authentication the certificate must be valid. Invalid certificates are only used to encrypt the connection.

Test cases:

openssl verify -CAfile server-ca.crt server.pem
openssl verify -CAfile cluster-ca.crt member.pem
openssl verify -CAfile cluster-ca.crt client.pem

# Verify server certificate:
openssl s_server -cert server.pem
# open another terminal
openssl s_client -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q

# Verify server and client certificate:
openssl s_server -cert server.pem -CAfile cluster-ca.crt -Verify 0
# open another terminal
openssl s_client -cert member.pem -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q
openssl s_client -cert client.pem -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q

Visualization

enter image description here

Or if you use only one CA certificate common-ca.crt:

enter image description here

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • thank you sir , helped a lot. been struggling with sharded cluster and x509 authenticadtion, the problem is that i create the user with its client certificate subject string in external databse, yet I'm unable to connect to mongos, it keeps saying UserNotFound. – Hirbod Jul 03 '23 at 15:29
  • @Hirbod Please open a new question for it – Wernfried Domscheit Jul 03 '23 at 21:26