How to use Node.js to make a SSH tunneling connection to a MongoDB database
Solution 1
As mscdex mentioned ssh2 isn't a good module to use to make an ssh tunnel connection to a database. tunnel-ssh is more appropriate.
Here are the configuration options I've used :
dstPort: remote database connection port
localPort: same as dstPort, It'll be the port you'll use for your local machine
username: SSH username,
host: SSH address
dstHost: database connection url (...mongodbns.com) ,
privateKey: SSH key
Then once your tunnel is connected connect via mongoose to your localhost such as mondodb://localhost:27000 (use the localport you defined in localPort)
var server = tunnel(config, function (error, server) {
if(error){
console.log("SSH connection error: " + error);
}
mongoose.connect('mongodb://localhost:27000/');
//...rest of mongoose connection
}
Solution 2
Since mongoose
does not support passing in a stream to use as the underlying connection, you will have to listen on a local port (e.g. 27000) and forward incoming connections to that port over the ssh connection.
Fortunately there exists third party modules that build on ssh2
that provide this kind of functionality for you, such as tunnel-ssh
. Try using one of those.
user3382714
Updated on June 04, 2022Comments
-
user3382714 almost 2 years
My credentials work perfectly with Robomongo but I can't make the connection with node.js
I have tried to make the connection using ssh2 and tunnel-ssh npm module and failed both times.
-The mongo connection does not require a password
-The ssh connection is made with a pem keyThis is the code I've used with ssh2 module, I can establish the tunneling correctly but the mongo connection fails
var Client = require('ssh2').Client; var conn = new Client(); conn.on('ready', function() { console.log('Client :: ready'); //mongo connection mongoose.connect('mongodb://localhost:27000/'); var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log("database connection established"); var users = db.collection('user'); var getallUsers = function (date, callback){ users.find({}).toArray(function(err,data){ callback(data); }) }; getallUsers(null, function (data){ console.log('data :'+ data); }); }); //end of mongo connection }).connect({ host: '**.**.**.**.**', port: 22, username: 'ec2-user', privateKey: key });
And the code the tunnel-ssh
var config = { dstPort: 27000, user: 'ec2-user', host: '**.**.**.**.**', privateKey: key }; var server = tunnel(config, function (error, server) { if(error){ console.log("SSH connection error: " + error); } console.log('database connection initalizing'); mongoose.connect('mongodb://localhost:27000/'); var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log("database connection established"); var users = db.collection('user'); var getallUsers = function (date, callback){ users.find({}).toArray(function(err,data){ callback(data); }) }; getallUsers(null, function (data){ console.log(data); }); }); });
I'm not sure whether to use the regular MongoDB connection string after establishing the tunnel or referring to the database as localhost such as
mongodb://localhost:portnumber.
or
mongodb://databasepath.subpath.mongodbdns.com:27000Localhost gives me a permission denied error, the latter gives me a timeout