3

I'm trying to connect through SSL to a local mongodb instance through libmongoc. The connection works just fine if I don't use SSL, and I can do CRUD operations normally, but when I enable SSL and try to retrieve some data, the mongoc_cursor_next() functions hangs for a long time, and then exits with false.

On the server's side, the logs shows that while it is stuck inside the function, the client connects to the server, has the connection accepted, disconnects, and repeats until it gets unstuck after a few minutes:

2019-02-13T15:34:45.792-0300 I NETWORK  [listener] connection accepted from 192.168.25.9:55256 #710 (1 connection now open)
2019-02-13T15:34:45.810-0300 I NETWORK  [conn710] received client metadata from 192.168.25.9:55256 conn710: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:45.810-0300 I NETWORK  [conn710] end connection 192.168.25.9:55256 (0 connections now open)
2019-02-13T15:34:46.311-0300 I NETWORK  [listener] connection accepted from 192.168.25.9:55258 #711 (1 connection now open)
2019-02-13T15:34:46.328-0300 I NETWORK  [conn711] received client metadata from 192.168.25.9:55258 conn711: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:46.328-0300 I NETWORK  [conn711] end connection 192.168.25.9:55258 (0 connections now open)
2019-02-13T15:34:46.829-0300 I NETWORK  [listener] connection accepted from 192.168.25.9:55260 #712 (1 connection now open)
2019-02-13T15:34:46.843-0300 I NETWORK  [conn712] received client metadata from 192.168.25.9:55260 conn712: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:46.843-0300 I NETWORK  [conn712] end connection 192.168.25.9:55260 (0 connections now open)

I initially thought that the fault was in my code, so I rebuilt the libmongoc library with the -DENABLE_TRACING=1 option, to see if I could pinpoint something that could help. But, to my surprise, this "fixed" the problem: it would not hang anymore on mongoc_cursor_next(), and the documents would return fine, but the tracing fills the stdout with excessive debug info, even dumping the TCP packets sent/received. If I enable the tracing, the problem vanishes. If I disable tracing, it comes back.

I tried to set the SSL options through the mongoc_client_pool_set_ssl_opts function, but the result is the same as passing them through the URI. I also tried to use a certificate on the client as well, but no luck either. The only things that worked was either building the libmongoc with -DENABLE_TRACING=1 or not using SSL on the client.

I don't know if it's something related to me using a self-signed certificate, since I don't have a trust-signed one. But I thought that the sslAllowInvalidCertificates=true was to ignore this requirement, since it's just a development database with mock data.

Am I missing something?

My Environment:

Clients:
Ubuntu 18.10 x64, libmongoc 1.13.1 / 1.9.5 (tested both), GCC 8.2.0
Windows 10 Pro, libmongoc 1.9.5, MSVC 2015.

Server:
Ubuntu 18.10 x64
MongoDB 4.0.6 (git version: caa42a1f75a56c7643d0b68d3880444375ec42e3)
OpenSSL version: OpenSSL 1.1.1 11 Sep 2018

My example client:

int main(int argc, char *argv[])
{
    mongoc_init();
    mongoc_uri_t *uri = mongoc_uri_new("mongodb://Client:1234@localhost/?authSource=MyDatabase&ssl=true&sslAllowInvalidCertificates=true");

    if(!uri)
    {
        std::cout << "Failed to parse URI";
        return 1;
    }

    mongoc_client_pool_t *pool = mongoc_client_pool_new(uri);
    mongoc_client_pool_set_appname(pool, "Test Client");
    mongoc_client_pool_set_error_api(pool, MONGOC_ERROR_API_VERSION_2);

    mongoc_uri_destroy(uri);

    mongoc_client_t *client = mongoc_client_pool_pop(pool);

    mongoc_collection_t *col = mongoc_client_get_collection(client, "MyDatabase", "MyCollection");

    bson_error_t err;

    bson_t *filter = bson_new_from_json(reinterpret_cast<const uint8_t*>("{}"), 2, &err);
    bson_t *opts = bson_new_from_json(reinterpret_cast<const uint8_t*>("{}"), 2, &err);

    if(!filter || !opts)
        return 2;

    mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(col, filter, opts, nullptr);
    bson_t *bson = nullptr;

    while(mongoc_cursor_next(cursor, const_cast<const bson_t **>(&bson)))
        std::cout << "Got document!" << std::endl;

    mongoc_cursor_destroy(cursor);

    mongoc_collection_destroy(col);

    mongoc_client_pool_push(pool, client);
    mongoc_client_pool_destroy(pool);

    mongoc_cleanup();

    return 0;
}

My server configuration (mongod.conf):

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0

  ssl:
    mode: allowSSL
    PEMKeyFile: /home/tyras/mongodb.pem
    allowConnectionsWithoutCertificates: true
    allowInvalidCertificates: true


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:
security:
  authorization: enabled

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:

EDIT:

After further testing I found out that when connecting without a pool, It doesn't get stuck on mongoc_cursor_next(). but fails, and mongoc_cursor_error() returns:

Error 13053: No suitable servers found (`serverSelectionTryOnce` set): [Failed to receive length header from server. calling ismaster on 'localhost:27017']

Also, I can connect normally through SSL with the mongo CLI and Compass.

Tyras
  • 103
  • 1
  • 7

0 Answers0