Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

Mongodb:// URI with X.509

Hello all,

I’ve been struggling with a URI connect issue for the last day or two, and have run out of options to try. Im hoping someone here will be able to answer my question.

The error I am getting is that the SSL handshake fails because no ssl certificate is presented in the URI string.

Background:

MongoDB 4.0 in a 5 server sharded cluster on EC2 instances - a test environment.
There is 1 Query/Router/Mongos, 1 config server and 3 sharded servers. (I understand this isn’t the ideal config but its for testing purposes).

x.509 is enabled and functioning properly (SSL is enforced, not optional) on the mongo shell level. In fact even with Studio 3T I can validate against the server using x.509 - and everything works fine. HOWEVER.

The problem comes when attempting to stitch together a URI for Meteor. Our application is packaged/bundled with Meteor - and is looking to connect to the mongo instance with mongodb://

This does seem to be a significant issue for Mongo to pass the location of the client PEM file and the CA PEM file to the mongos instance.

For security reasons Im reluctant to share the full connect string Im using - and I realize that makes it difficult for folks to help, so I’ve altered it to take it out the sensitive details. The *'s are obviously the data I’ve removed. The string below works from a 3T query perspective. However, if I take out the 3T extensions (3T.rootCApath - etc.) it obviously does not work. I have tried several combinations instead to pick up the pem files such as:

mongodb://C%3D**%2CST%3D**%2CL%3D*****%2CO%3D********%2COU%3D*****%2CCN%3D****%2CemailAddress%3D**40.com@localhost:9999/?ssl=true&sslInvalidHostNameAllowed=true&readPreference=primary&serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=$external&authMechanism=MONGODB-X509&3t.uriVersion=3&3t.connection.name=Mongo+Dev+Shard&3t.certificatePreference=RootCACert:from_file&3t.rootCAPath=C:\Documents*CA.pem&3t.clientCertPath=C:\Documents*.pem&3t.useClientCertPassword=true

sslCertificateKeyfile=
sslCAFile=
clientCertPath=
CAPath=
ssl_certfile=
ssl_ca_certs=
sslPEMKeyFIle=
sslPEMKeyPassword=
sslCAFile=
sslCertificateKeyfile=
sslCertificateKeyFilePassword=

Here is an example of what I have used (numerous variations) of a string where the 3T items are removed:

mongodb://C%3D**%2CST%3D**%2CL%3D******%2CO%3D***********%2COU%3D*******%2CCN%3D******%2CemailAddress%3D****%40*******.com@localhost:9999/?ssl=true&sslInvalidHostNameAllowed=true&sslCertificateKeyfile=C:\FileBuilds*.pem&sslCAFile=C:\FileBuilds*.pem&sslCertificateKeyFilePassword=’*************’&readPreference=primary&serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=$external&authMechanism=MONGODB-X509

//////
Lastly -and this is more for feedback purposes in the event anyone from the MongoDB team reads this. The documentation on how to use x.509 authorization with URI’s seems quite sparse to me, and difficult to come by. The information presented is very highly level, incomplete, and leads to the user to a conclusion that it should be quite easily achievable to use X.509 with a URI. As some of you may have discovered - setting up x.509 with a sharded cluster is not a trivial task and is a time sink - one would expect that implementing a supported security approach should result in the ability to use published/supported mechanisms to connect. Username formatting (particularly around the %hex value replacement of ‘reserved characters’) appears to be dated, difficult to locate in the documentation, and not at all obvious.

Secondly - key words regarding how to pass the SSL PEM file is not directly addressed, other than for tls - and then its unclear whether ssl(keyword) is a valid usage in the connect string, and whether tls(keyname) is even supported. I understand they may have deprecated SSL - however if they are going to allow ssl=true - then the supporting documentation should be there to understand how to implement it. If x.509 is not intended to be used with a URI string - that should be stated obviously so that the user/architect can make an informed choice when it comes to implementation. ///‘feedback’ over.

Hi Eric,

The official Node driver supports TLS connection options using an options object (see MongoClient.connect(), however I can’t find the relevant documentation on the Meteor side.

Presumably, if Meteor allows passing the connection options object to the Node driver (I’m assuming they use the official Node driver under the hood), you should be able to connect using the method described in the Node driver page.

The only resource I can find is this Meteor forum post regarding this exact issue.

Best regards,
Kevin

1 Like