C++ driver tutorial questions

890 views
Skip to first unread message

Jeff Abrahamson

unread,
Oct 6, 2016, 1:44:16 PM10/6/16
to mongodb-user, Andrew Morrow
Thanks to acm, I'm able to compile the provided sample C++ program.  I'll start a new thread for some new questions.
  • The tutorial says that one merely needs a mongod running on localhost:27017 and the sample program will connect to a test db and test collection. Nice, but not my experience. But since I haven't connected to anything yet, maybe it's my fault and not that the local mongod needs some special incantation.

terminate called after throwing an instance of 'mongocxx::v_noabi::bulk_write_exception'
  what():  No suitable servers found (`serverSelectionTryOnce` set): [Server closed connection. calling ismaster on 'localhost:27017']: generic server error
Aborted (core dumped)

  • So, I know how to connect to my usual mongod.  I just say this:

        mongo localhost:27017/my_dbname --ssl -u my_db_username -p

    and then I enter my password.  The docs don't seem to suggest how to authenticate.  No problem, I look in the headers.  I see I can pass an options::client object to the client constructor.  In mongocxx/options/client.hpp I find mongocxx::client::options, which has an ssl_opts field, but it's not quite clear to me how to use it. It asks for things like the locations of pem files and such which are local to the server.  Surely this can't be the right path.  And I find no mention of db username and password, though the uri class permits me to query for the password that apparently I can supply.
Thanks much for any pointers.

Jeff Abrahamson

unread,
Oct 7, 2016, 3:20:10 AM10/7/16
to mongodb-user, Andrew Morrow
Some progress on making the connection.  Reading uri.hpp, I find a pointer to http://docs.mongodb.org/manual/reference/connection-string .  So now I know to specify my connection string thus:

mongocxx::uri uri{"mongodb://db_username:db_password@localhost:27017/db_name?ssl=true"};

Running my test program, I see this error:

jeff@birdsong:mongodb $ ./hw
terminate called after throwing an instance of 'mongocxx::v_noabi::query_exception'
  what():  No suitable servers found (`serverSelectionTryOnce` set): [TLS handshake failed: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed calling ismaster on 'localhost:27017']: generic server error
Aborted (core dumped)
134, jeff@birdsong:mongodb $


Watching the mongodb logs (progress!), I see this (where, of course, my IP address is not really 1.2.3.4):

2016-10-07T08:13:38.381+0100 [initandlisten] connection accepted from 1.2.3.4:41482 #41578 (10 connections now open)
2016-10-07T08:13:38.523+0100 [conn41578] ERROR: SSL: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
2016-10-07T08:13:38.523+0100 [conn41578] end connection 1.2.3.4:41482 (9 connections now open)

So I've succeeded in requesting an SSL connection, but not in connecting.  (And using the mongo commandline client, I know that connection with this user/pass is at least possible.)

Jeff Abrahamson

unread,
Oct 7, 2016, 3:55:04 AM10/7/16
to mongodb-user, Andrew Morrow
Probably my code is wrong and yet I neglected to include it.

In python (pymongo.MongoClient), I can successfully connect thus:

mongo_url = 'mongodb://db_username:db_password@localhost:27017/db_name'
client = MongoClient(mongo_url, ssl=True, ssl_cert_reqs=ssl.CERT_NONE)
db = client[dbname]

In C++, I am trying this:

mongocxx::uri uri{"mongodb://db_username:db_password@localhost:27017/db_name?ssl=true"};
mongocxx::options::client client_options;
if (uri.ssl()) {
    mongocxx::options::ssl ssl_options;
    client_options.ssl_opts(ssl_options);
}

mongocxx::client conn{uri, client_options};

mongocxx::database db = conn["db_name"];    // ???
mongocxx::collection collection = db["my_collection"];

auto maybe_result =
    collection.find_one(bsoncxx::builder::stream::document{}
            << "field_1" << 46 << "field_2" << 4202
            << bsoncxx::builder::stream::finalize);
// Error emitted here.

David Golden

unread,
Oct 7, 2016, 9:55:45 AM10/7/16
to mongodb-user, andrew...@mongodb.com
Hi, Jeff.

Are you using a self-signed certificate?  The key phrase in the error is "ssl3_get_server_certificate:certificate verify failed". That looks like the cert isn't valid.  By default libmongoc and thus mongocxx uses the default CA list for your operating system.

David

David Golden

unread,
Oct 7, 2016, 9:58:14 AM10/7/16
to mongodb-user, andrew...@mongodb.com
FYI, I've filed CXX-1075 about improving the manual for auth and SSL.

David Golden

unread,
Oct 7, 2016, 10:02:06 AM10/7/16
to mongodb-user, andrew...@mongodb.com
If you have your own cert, you need to tell the driver what to do about it.  You can set client options with custom SSL options.  You can add your own CA file or you can disable verification.

Jeff Abrahamson

unread,
Oct 10, 2016, 8:09:11 AM10/10/16
to mongodb-user, Andrew Morrow
I see on the google groups web site that David replied a couple days ago. Strangely, I didn't get mail.  Sorry for the response delay.

David wrote:
> Are you using a self-signed certificate?  The key phrase in the error is "ssl3_get_server_certificate:certificate verify failed". That looks like the cert isn't valid.  By default libmongoc and thus mongocxx uses the default CA list for your operating system.

Answer: I am nearly certain we are using a properly signed certificate. Maybe I am looking at the wrong pem file. I don't know how to check remotely (i.e., by querying via tcp in an unprivileged way), I'm open to pointers.

(And: thanks for filing the bug about auth examples.)

What is strange to me is that the pymongo auth goes fine. I recall that I did have to fiddle a bit before discovering that I needed to say ssl_cert_reqs=ssl.CERT_NONE in the python connection request. I've been dragging me feet about downloading the pymongo source code to figure out what that translates to in terms of libmongoc...

David Golden

unread,
Oct 10, 2016, 11:29:17 AM10/10/16
to mongodb-user, andrew...@mongodb.com
On Monday, October 10, 2016 at 8:09:11 AM UTC-4, Jeff Abrahamson wrote:
Answer: I am nearly certain we are using a properly signed certificate. Maybe I am looking at the wrong pem file. I don't know how to check remotely (i.e., by querying via tcp in an unprivileged way), I'm open to pointers.


You could try the approach in "How to verify SSL certificate from a shell prompt".
 
What is strange to me is that the pymongo auth goes fine. I recall that I did have to fiddle a bit before discovering that I needed to say ssl_cert_reqs=ssl.CERT_NONE in the python connection request. I've been dragging me feet about downloading the pymongo source code to figure out what that translates to in terms of libmongoc...

That's a good hint that it's a cert verification problem.  See the Pymongo TLS docs.  Setting the same for mongocxx should be pretty straightforward.  Try something like this (with your actual connection URI of course, including ssl=true):

   auto uri = mongocxx::uri{"mongodb://localhost:27017?ssl=true"};

   auto opts_ssl = mongocxx::options::ssl{};
   opts_ssl.allow_invalid_certificates(true);

   auto opts_client = mongocxx::options::client{};
   opts_client.ssl_opts(opts_ssl);

   auto client = mongocxx::client(uri, opts_client);


Regards,
David

Jeff Abrahamson

unread,
Oct 11, 2016, 2:53:15 AM10/11/16
to mongodb-user, andrew...@mongodb.com, Jeff Abrahamson
On Monday, 10 October 2016 17:29:17 UTC+2, David Golden wrote:
On Monday, October 10, 2016 at 8:09:11 AM UTC-4, Jeff Abrahamson wrote:
Answer: I am nearly certain we are using a properly signed certificate. Maybe I am looking at the wrong pem file. I don't know how to check remotely (i.e., by querying via tcp in an unprivileged way), I'm open to pointers.


You could try the approach in "How to verify SSL certificate from a shell prompt".

Oh, of course. Thanks!

And that confirms that my cert is, indeed, self-signed. Seems mongo was set up here a _very_ long time ago.


What is strange to me is that the pymongo auth goes fine. I recall that I did have to fiddle a bit before discovering that I needed to say ssl_cert_reqs=ssl.CERT_NONE in the python connection request. I've been dragging me feet about downloading the pymongo source code to figure out what that translates to in terms of libmongoc...

That's a good hint that it's a cert verification problem.  See the Pymongo TLS docs.  Setting the same for mongocxx should be pretty straightforward.  Try something like this (with your actual connection URI of course, including ssl=true):

   auto uri = mongocxx::uri{"mongodb://localhost:27017?ssl=true"};

   auto opts_ssl = mongocxx::options::ssl{};
   opts_ssl.allow_invalid_certificates(true);

   auto opts_client = mongocxx::options::client{};
   opts_client.ssl_opts(opts_ssl);

   auto client = mongocxx::client(uri, opts_client);

And that does it. Thanks!

Jeff

Reply all
Reply to author
Forward
0 new messages