Connect Meteor.js with Mongo using X509 auth certificate

I am trying to configure passwordless authentication between Meteor.js applications and a Mongo server.

To do this, I need to submit the pem and crt files to connect. The MONGO_URL connection string accepts only parameters on how to run auth, but does not reference certificate files. I assume that I need to pass the certificate file to the connection as a parameter. As described in here .

How to do it in Meteor.js?

Basically I want to achieve the equivalent:

mongo mongo.example.com/example -ssl -sslPEMKeyFile client.pem --sslCAFile server.crt 

and then as described here

 db.getSiblingDB("$external").auth( { mechanism: "MONGODB-X509", user: "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry" } ) 

this works fine when using the mogo client, but inside Meteor I still only realized that I would most likely need to use the connection string below (or something similar)

 MONGO_URL=mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509 

but the question remains - how to transfer certificates to the connection?

Update: there is an answer that concerns the problem using the noddejs mongo native driver. the question is how to transfer this to Meteor.

Update 2015-12-31: I accepted a response that indicates the use of another connection object when defining a collection. It is a hassle to do this for each collection separately, but it seems to be the only way to do it right now. In addition, if the need arises, some MySslCollection may be created, which others may use to inherit the connection details. This has not been verified.

+6
source share
3 answers

Updated answer (version 1.4 and higher)

As indicated in another answer, the parameters here have changed since version 1.4, and now you can call

Mongo.setConnectionOptions({ ... });

See the documentation for more details.

Old Answer (Preview 1.4)

It was a fun hole for rabbits ... I think I found one solution / workaround for your problem (there may be others).

A short description of my workaround is to specify the mongodb server settings when creating your collections. This must be done only on the server code, so as not to distribute your ssl / cert key. For instance:

 new Mongo.Collection("collection_name", { connection: DDP.connect("mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509", { server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }) }); 

Hakki

Since you asked if there was a way to do this without adding parameters to each created collection, I decided to take another look. I have not tested these methods, but they seem sound if they are very hacks.

1) Configure the function to run in the connection state using the argument of undocumented parameters passthru in the reconnection method. https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L996

 Tracker.autorun(function () { var status = Meteor.status(); if(status == 'failed') Meteor.reconnect({ server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }); }); 

2) Monkey fixes the connection code by default (I am less sure of this, since I did not find the time to understand when the mongo internal code for this is actually installed in the first place). https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/remote_collection_driver.js

 MongoInternals.defaultRemoteCollectionDriver = _.once(function () { var connectionOptions = { server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }; var mongoUrl = process.env.MONGO_URL; if (process.env.MONGO_OPLOG_URL) { connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL; } if (! mongoUrl) throw new Error("MONGO_URL must be set in environment"); return new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions); }); 

Journey to these answers:

Starting with the answer you linked, I found that Meteor is creating its MongoDB connection: https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/mongo_driver3.js#

Then I found where this is called: https://github.com/meteor/meteor/blob/3d2282d9ad0b570b913a70d215cd968019d912df/packages/mongo/remote_collection_driver.js#L4

Keeping track of what caused the call has led me to make collections create a connection: https://github.com/meteor/meteor/blob/15cdbca24888bfdff3ad43c1891a1719c09b3dc5/packages/mongo/collection.js#L102

I could see from there that some options could override the use of the default Mongo binding, which has no options. A look in the Meteor docs for the http://docs.meteor.com/#/full/mongo_collection collections shows:

Functions

connection object

The connection to the server that will manage this collection. Uses the default connection if not specified. Pass the return value of the DDP.connect call to indicate a different server. Pass null to indicate a connection. Unmanaged (name null) collections cannot indicate a connection.

Therefore, looking at the documents for DDP.connect http://docs.meteor.com/#/full/ddp_connect , we reach a dead end, since it takes only the URL ... but wait ... after searching the code in github I see that DDP.connect accepts param parameters: https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L1641

Thus ends our quest.

+5
source

Since Meteor 1.4, Mongo connection options can be configured by calling:

 Mongo.setConnectionOptions({ ... }); 

The function must be called earlier during initialization. One way is to create a local Meteor package that loads before other packages. See https://forums.meteor.com/t/meteor-with-the-new-mongodb-3-2-1-compose-io/17763/10 and Meteor GitHub issue No. 7455 for more details.

Meteor 1.4 Release Notes: https://github.com/meteor/meteor/blob/devel/History.md#v14-2016-07-25

+2
source

Both of the previous answers are correct ( craigts , user1887896 ), however I would like to add:

  • I put a very simple package on Atmosphere ( danwild: set-connection-options ) to simplify this process (or at least provide a specific example of how and where Mongo.setConnectionOptions can actually be used, since there is little documentation) .
  • I repeat that if you use any packages that access Mongo in your project (for example, accounts-base ), you must make sure that your call to Mongo.setConnectionOptions occurs before they are downloaded.
    • How to do it? Good question.
    • As far as I see, there is no official way to ensure that a package is downloaded before another (on the contrary, it is well supported).
    • The easiest way I've seen is to edit the package order in .meteor/packages , i.e. place danwild:set-connection-options at the top of the file.
+2
source

All Articles