How do I connect to a MongoDB Database using SSL with Loopback - mongodb

I am trying to connect to a MongoDB Database in Rackspace w/ SSL using loopback, but it's not working. It seems to connect fine; if I enter wrong credentials (on purpose) I get an error message saying "Can't connect", but when I use the correct credentials no error shows so I THINK I'm connecting fine. But when I try to query the database it always timesout, any idea whats happening?
My datasources.json looks something like:
"db": {
"name": "mongodb",
"url": "mongodb://username:password#iad-mongos2.objectrocket.com:port/dbName?ssl=true",
"debug": true,
"connector": "mongodb"
}
I keep reading things about needing a certificate file, but not sure if that applies in this case.
Any help would be greatly appreciated!

use datasources.env.js as below
var cfenv = require('cfenv');
var appenv = cfenv.getAppEnv();
// Within the application environment (appenv) there's a services object
var services = appenv.services;
// The services object is a map named by service so we extract the one for MongoDB
var mongodb_services = services["compose-for-mongodb"];
var credentials = mongodb_services[0].credentials;
// Within the credentials, an entry ca_certificate_base64 contains the SSL pinning key
// We convert that from a string into a Buffer entry in an array which we use when
// connecting.
var ca = [new Buffer(credentials.ca_certificate_base64, 'base64')];
var datasource = {
name: "db",
connector: "mongodb",
url:credentials.uri,
ssl: true,
sslValidate: false,
sslCA: ca
};
module.exports = {
'db': datasource
};
http://madkoding.gitlab.io/2016/08/26/loopback-mongo-ssl/
https://loopback.io/doc/en/lb3/Environment-specific-configuration.html#data-source-configuration

Create a Datasource using lb4 datasource command, edit the datasource generated by adding the SSL details to the config object: 'ssl', 'sslvalidated', 'checkserverIdentity, sslCA, sslKey etc.
import fs from 'fs';
import path from 'path';
const ca = fs.readFileSync(
path.join(__dirname, '../../utils/certs/mongodbca.cert'),
'utf8',
);
const config = {
name: 'test_db',
debug: true,
connector: 'mongodb',
url: false,
host:'hostname',
port: port,
user: 'user',
password: 'password',
database: 'databasename',
authSource: 'admin',
useNewUrlParser: true,
ssl: true,
sslValidate: true,
checkServerIdentity: false,
sslCA: [ca],
};

This worked for me, You can monkey patch the Mongo.connect() function by which you can add the option parameter.
Make a boot script file which can use the MongoDB option parameters of SSL certificate to make a secured connection to MongoDB, below code snippet, is written in a boot script js.
//Below code is written in a boot script
var monog_cert_file = fs.readFileSync(path.join(__dirname, '../certificate_dir/mongodb.pem'));
var monog_ca_file = fs.readFileSync(path.join(__dirname, '../certificate_dir/rootCA.pem'));
var monog_key_file = fs.readFileSync(path.join(__dirname, '../certificate_dir/mongodb.pem'));
const mongoOptions = {
ssl: true,
sslValidate: false,
sslCA:monog_ca_file,
sslKey:monog_key_file,
sslCert:monog_cert_file,
authSource:"auth_db_name"
};
//Patching Mongo connect For option variable
const mongodb = require('mongodb').MongoClient;
const ogConnect = mongodb.connect;
const connectWrapper = function(url,cb) {
return ogConnect(url, mongoOptions, cb);
}
mongodb.connect = connectWrapper;
//Patching Mongo connect For option variable

use datasources.json as below
app_db: {
"host": "127.0.0.1",
"port": 27017,
"database": "test",
"name": "app_db",
"username": "youruser",
"password": "yourpassword",
"connector": "mongodb",
"ssl":true,
"server": {
"auto_reconnect": true,
"reconnectTries": 100,
"reconnectInterval": 1000,
"sslValidate":false,
"checkServerIdentity":false,
"sslKey":fs.readFileSync('path to key'),
"sslCert":fs.readFileSync('path to certificate'),
"sslCA":fs.readFileSync('path to CA'),
"sslPass":"yourpassphrase if any"
}
username,
password,
auto_reconnect,
tries and interval all are optional.
use below link to get the certificates using OpenSSL
https://docs.mongodb.com/manual/tutorial/configure-ssl/

Related

How to connect PostgreSQL Database to Cypress 10+ , no pg_hba.conf entry error

When I try to connect and query on my PostgreSQL database, I keep getting a cypress error: “no pg_hba.conf entry for host “ user “postgres”, database “postgres”, SSL off”. How do I solve the error. Is this an issue with code or with the database?
this is my cypres.config.js file:
const pg = require("pg")
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on("task", {
//create a task - take two parameters - first being a config and second is sql
READFROMDB({ dbConfig, sql }) {
//create a client using the config argument
const client = new pg.Pool(dbConfig)
//return thw result from sql
return client.query(sql)
}
})
},
DB:{
database: "<name>",
user: "<name>",
password: "<pw>",
host: "<hostname>.amazonaws.com", //not localhost
port: 5432,
dialect: "postgres",
dialectOptions: {
ssl: {
require: true, // This will help you. But you will see nwe error
rejectUnauthorized: false // This line will fix new error
}
}
}
}
})
This is my test:
cy.task("READFROMDB",{
//get config from db
dbConfig: Cypress.config('DB'),
//SQL we want to perform
sql: 'select * from user where user=\'Phoebe\''
}).then((result)=>{
console.log(result.rows)
})

Heroku Postgres - The server does not support SSL connections

I have been working on an small app and connecting with Heroku PostgreSQL, for many days was working right but now is showing me this SSL error
The server does not support SSL connections
I have been looking for solutions but I cannot find anything that works for me, my code is:
import pg from 'pg'
import db from '../config.js'
const pool = new pg.Pool({
host: db.host,
database: db.database,
user: db.user,
port: db.port,
password: db.password,
ssl: { rejectUnauthorized: false },
})
export default function query(text, params) {
return pool.query(text, params)
}
Try changing it from Pool to Client and then using that to connect and query.
async function get(){
const client = new pg.Client({
ssl: {
rejectUnauthorized: false
},
user: ...,
password: ...,
port: ...,
host: ...,
database: ...
});
client.connect();
const response = await client.query(`SELECT * FROM ...;`)
return response.rows
}
Double check your values in the Heroku database.
Also, in production, you should just need
const client = new pg.Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
},
}
The first set of code is for local connection to your db.
One last note, I would put your user, password, etc... into a .env file and don't commit that to your repo.
UPDATE:
You can also put this into a config file like ./db.config.js as the following
const pg = require('pg')
module.exports =
process.env.DATABASE_URL
?
new pg.Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
},
})
:
new pg.Client({
// connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
},
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
port: process.env.DATABASE_PORT,
host: process.env.DATABASE_HOST,
database: process.env.DATABASE
})
So if it is in production, it will use the database url, and if there is none (which is local) then it will use the username password connection.

How can I set TLS for Mongoose connection

I'm trying to migrate my mongo database from Compose to IBM Cloud Databases for Mongo and in their documnetations (https://www.compose.com/articles/exporting-databases-from-compose-for-mongodb-to-ibm-cloud/): "With a new Databases for MongoDB deployment, you'll be provided with a replica set of two endpoints to connect to your database. Databases for MongoDB also uses a TLS certificate, so you'll need to configure your MongoDB application driver to accept two hosts and a TLS certificate"
How can I set the TLS certificate provided by IBM Cloud in Mongoose connection ?
Nothing I've tried worked :(
I can see my database if I'm using the IBM cli but from my node.js application I cannot connect to it
var mongoose = require('mongoose');
mongoose.Promise = Promise;
var uri="mongodb://admin:passSftgdsdfvrrdfs#host1-1231243242.databases.appdomain.cloud:32605,host2-1231243242,host1-1231243242/testDatabaseName?authSource=admin&replicaSet=replset"
myDb.db = mongoose.createConnection(uri, {
tls: true,
tlsCAFile:`076baeec-1337-11e9-8c9b-ae5t6r3d1b17` (this is the name of the certificate and is placed in the root)
// tlsCAFile: require('fs').readFileSync('041baeec-1272-11e9-8c9b-ae2e3a9c1b17') // I have also tried something like this
absolute nothing is working even the database is there
Please help me
I'm also facing same problem
this works for me
mongoose.connect(‘mongodb+srv://username:password#host/db_name?authSource=admin&replicaSet=repliasetname&tls=true&tlsCAFile=/root/ca-certificate.crt’,{some config})
Try the following:
var key = fs.readFileSync('/home/node/mongodb/mongodb.pem');
var ca = [fs.readFileSync('/home/node/mongodb/ca.pem')];
var o = {
server: {
ssl: true,
sslValidate:true,
sslCA: ca,
sslKey: key,
sslCert:key
},
user: '****',
pass: '****'
};
m.connect('mongodb://dbAddr/dbName', o)```
I did it locally, you need to install the tunnel first
$ ssh -i "IF YOU HAVE PEM.pem" -L <27017:YOUR_AMAZON_HOST:27017> <server_user_name#server_ip_OR_server_url> -N
I managed to implement it as follows
const CERTIFICATE_PATH = 'rds-combined-ca-bundle.pem'
const certificateCA = CERTIFICATE_PATH && [fs.readFileSync(CERTIFICATE_PATH)];
const sslOptions = certificateCA
? ({
ssl: true,
tlsAllowInvalidHostnames: true,
sslCA: certificateCA,
user: MONGODB_USER,
pass: MONGODB_PASSWORD,
} as ConnectionOptions)
: {};
const options: ConnectionOptions = {
...sslOptions,
};
export const connectMongoDb = async (): Promise<void> => {
await mongoose.connect('mongodb://localhost:27017/test', options);
console.log('📊 Successfully connected to the database');
};
You need to set
MONGODB_USER
MONGODB_PASSWORD

deno connect to mongodb

I've tried to follow this tutorial https://www.youtube.com/watch?v=VF38U2qd27Q, but to no avail.
I realised that the syntax in the video already obsolete for example connectWithUri to become connect.
but when I tried to connect to mongo using deno_mongo with the latest docs, it still not working.
import { MongoClient } from "https://deno.land/x/mongo#v0.20.1/mod.ts";
const dbString = `mongodb://${mongoUser}:${mongoPass}#${mongoHost}:${mongoPort}`;
const client = new MongoClient();
client.connect(dbString);
const db = client.database(mongoDB)
this.users = db.collection<UserSchema>("users");
Then I found another library denodb but again can't connect to mongodb:
import { Database } from 'https://deno.land/x/denodb/mod.ts';
const dbString = `mongodb://${mongoUser}:${mongoPass}#${mongoHost}:${mongoPort}`;
this.db = new Database('mongo', {
uri: dbString,
database: mongoDB
});
the error message:
error: Uncaught AssertionError
deno | throw new AssertionError(msg);
deno | ^
deno | at assert (asserts.ts:152:11)
deno | at MongoClient.database (client.ts:48:5)
deno | at new connectDB (connectDB.ts:35:23)
which part is wrong?
Looking at the deno_mongo README on GitHub.
For a local database you should use
//Connecting to a Local Database
await client.connect("mongodb://localhost:27017");
And if you are connecting to Mongo Atlas Database (and probably any other remote database) you should use:
//Connecting to a Mongo Atlas Database
await client.connect({
db: "<db_name>",
tls: true,
servers: [
{
host: "<db_cluster_url>",
port: 27017,
},
],
credential: {
username: "<username>",
password: "<password>",
db: "<db_name>",
mechanism: "SCRAM-SHA-1",
},
});
FYI
If you are using Mongo Atlas make sure to split up the connection string you get from 'Connection Wizard' in the Mongo Atlas dashboard over 3 (or how many replicas you have) entries in the server array. Like this:
servers: [
{
host: this.dbUrl1, // e.g. <name-of-cluster>-00-00.fbnrc.mongodb.net
port: 27017,
},
{
host: this.dbUrl2, // e.g. <name-of-cluster>-00-01.fbnrc.mongodb.net
port: 27017,
},
{
host: this.dbUrl3, // e.g. <name-of-cluster>-00-02.fbnrc.mongodb.net
port: 27017,
}
]
You get the connection string by:
Click 'Clusters' under Data storage (left side of the screen)
Click 'Connect' button
Click 'Connect to Application'
Select Driver: 'Node.js' and Version: '2.2.12 or later'
Connection string is displayed below. The servers are listed in a comma separated manner like this:
...<name-of-cluster>-00-00.fbnrc.mongodb.net:27017,<name-of-cluster>-00-01.fbnrc.mongodb.net:27017,<name-of-cluster>-00-02.fbnrc.mongodb.net:27017...
FYI-2
Make sure the master replica is listed first in the server array. Because if you want to do insertions into the database the master replica should be targeted. For me this was the 2nd mongo url, therefore the following server array worked for me:
servers: [
{
host: this.dbUrl2,
port: 27017,
},
{
host: this.dbUrl1,
port: 27017,
},
{
host: this.dbUrl3,
port: 27017,
}
]
the below code is working for me.
import { DataTypes, Database, Model } from 'https://deno.land/x/denodb/mod.ts';
const db = new Database('mongo', {
host: 'mongodb://localhost:27017',
username: '',
password: '',
database: 'DBMYAPP',
});
console.log(db)
I also faced the same issue while updating deno_mongo to the latest version. Use await to resolve client.connect method
Try this:
import { MongoClient } from "https://deno.land/x/mongo#v0.20.1/mod.ts";
const dbString = `mongodb://${mongoUser}:${mongoPass}#${mongoHost}:${mongoPort}`;
const client = new MongoClient();
await client.connect(dbString);
const db = client.database(mongoDB)
this.users = db.collection<UserSchema>("users");
I had the same problem on windows 10, so try this
on your local mongodb:
await client.connect("mongodb://127.0.0.1:27017");

I can not connect to monogdb with mongoose when authorization enabled

I am trying to connect with MongoDB by mongoose. Everything was ok, when I was connecting with my local db where there is no authentication.
When I've tried to connect to other DB with set admin user and credentials, I've got error and I've tried various different options but without any positive result.
I use these versions:
"mongodb": "^3.3.2",
"mongoose": "^5.7.1"
And my server side technology is node.js
I've tried these options:
const connection = await mongoose.connect(`mongodb://${host}:${port}/${db}?authSource=admin`,
{ useNewUrlParser: true, useUnifiedTopology: true });
then I've tried this:
let options = {
"auth": { "authSource":"admin"},
"user": "SVSAdmin",
"pass":"8&PG2DCUuDPvy$hx",
"useUnifiedTopology": true,
"useNewUrlParser": true
};
const connection = await mongoose.connect(`mongodb://${host}:${port}/${db}, options);
and this:
mongoose.connect('mongodb://${user}:${pass}#${uri}/${db}?authMechanism=SCRAM-SHA-1')
mongoose.connect('mongodb://${user}:${pass}#${uri}/${db}?authMechanism=MONGODB-CR')
and also this:
mongoose.connect('mongodb://user:password#host/yourDB?authSource=admin&w=1')
but it does not work. My credentials are ok.
The error message is:
{
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {}
}
Maybe important thing is that I'm connecting with db by ssh
I would be grateful for any help.
If u are using ur database remotly then u can use it via IP.
db = mongodb://52.221.52.32/DataBaseName