1

I'm having trouble connecting to MongoDB from Loopback 4. We have lots of services that connect to MongoDB from Loopback 3, but this is the first attempt at using Loopback 4. The error I'm getting is:

(node:1) [MONGODB DRIVER] Warning: Top-level use of w, wtimeout, j, and fsync is deprecated. Use writeConcern instead.
(Use `node --trace-warnings ...` to show where the warning was created)
Server is running at https://[::1]:8000
Connection fails: MongoServerSelectionError: unsupported certificate purpose
It will be retried for the next request.
/usr/src/app/node_modules/mongodb/lib/utils.js:698
          throw error;
          ^

MongoServerSelectionError: unsupported certificate purpose
    at Timeout._onTimeout (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:438:30)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7)
Emitted 'error' event on DbDataSource instance at:
    at DbDataSource.postInit (/usr/src/app/node_modules/loopback-datasource-juggler/lib/datasource.js:502:16)
    at onError (/usr/src/app/node_modules/loopback-connector-mongodb/lib/mongodb.js:316:21)
    at /usr/src/app/node_modules/loopback-connector-mongodb/lib/mongodb.js:324:9
    at /usr/src/app/node_modules/mongodb/lib/utils.js:695:9
    at /usr/src/app/node_modules/mongodb/lib/mongo_client.js:260:23
    at connectCallback (/usr/src/app/node_modules/mongodb/lib/operations/connect.js:365:5)
    at /usr/src/app/node_modules/mongodb/lib/operations/connect.js:552:14
    at Object.connectHandler [as callback] (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:286:11)
    at Timeout._onTimeout (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:443:25)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7) {
  reason: TopologyDescription {
    type: 'ReplicaSetNoPrimary',
    setName: null,
    maxSetVersion: null,
    maxElectionId: null,
    servers: Map(3) {
      'replica01:27017' => [ServerDescription],
      'replica02:27017' => [ServerDescription],
      'replica03:27017' => [ServerDescription]
    },
    stale: false,
    compatible: true,
    compatibilityError: null,
    logicalSessionTimeoutMinutes: null,
    heartbeatFrequencyMS: 10000,
    localThresholdMS: 15,
    commonWireVersion: null
  }
}

Here is the code I'm using to connect (this was generated with the lb4 datasources command):

import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';

const config = {
  name: 'db',
  connector: 'mongodb',
  url: 'mongodb://replica01:27017,replica02:27017,replica03:27017/mydb?replicaSet=rs0&ssl=true&tlsCAFile=/etc/mongo-cert/mongoCA.pem',
  host: 'mongo',
  port: 27017,
  user: '',
  password: '',
  database: 'mydb',
  useNewUrlParser: true,
  ssl: true,
  sslCA: '/etc/mongo-cert/mongoCA.pem',
  debug: true
};

// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
@lifeCycleObserver('datasource')
export class DbDataSource extends juggler.DataSource
  implements LifeCycleObserver {
  static dataSourceName = 'db';
  static readonly defaultConfig = config;

  constructor(
    @inject('datasources.config.db', {optional: true})
    dsConfig: object = config,
  ) {
    super(dsConfig);
  }
}

Initially, I was using version 5.5.0 of loopback-connector-mongodb, but tried upgrading to 6.0.1, with no change.

If anyone has any thoughts on how to fix this error, I would greatly appreciate it.

piccy
  • 336
  • 2
  • 12
  • Your config is confused. You specify a URL parameter, but then also supply host, prot, user, password, database, etc. Choose one method and remove the other. My recommendation is to use URL and remove the host, port, user, password, and database parameters. Next, your url should have a user and password in the url value unless you have auth disabled. Next, your host names are odd. Do you have hosts with resolvable host names 'replica01', 'replica02', and 'replica03' visible from your Loopback4 host? Does this cluster have a replicaset called 'rs'? – barrypicker May 27 '21 at 21:37
  • Also, upon a failure, review the mongod log files, specifically the primary. It should reveal any abnormal connection problems. – barrypicker May 27 '21 at 21:39
  • @barrypicker Thanks. Those are sensible suggestions, but we use the exact same configuration in our 30+ Loopback 3 services, and they work just fine (albeit with an earlier version of loopback-connector-mongodb). I went ahead and deleted the host, port, user, password, and database parameters and got the same result. – piccy May 28 '21 at 15:19
  • Here is a similar issue - has to do with SSL Certificate v3 extended key usage and the cert purpose - assuming you have these extensions defined. https://stackoverflow.com/questions/61962285/mongodb-ssl-replica-setup-issues-unsupported-certificate. You could determine if certs are the problem by altering your configuration to not use certs. If connection succeeds you know the cert definitions is your guy, then change your config back to using certs and fix the condition. By the way, are you using bi-directional SSL? – barrypicker May 28 '21 at 15:59
  • @barrypicker I tried using the setting ```tlsAllowInvalidCertificates=true```, and the connection succeeded, so certs are definitely the issue. But I'm still in the dark as to why a similar setup works in Loopback 3, but not Loopback 4. – piccy May 28 '21 at 18:27
  • I assume you are using the same certs on LB3 vs. LB4? Or are the certs newly generated for new environment? – barrypicker May 28 '21 at 18:49
  • @barrypicker It's all one environment. All services use the same certs. – piccy May 28 '21 at 19:19

0 Answers0