Node.js tunneling to MongoDB Atlas replica set via bastion host

Hi all,

I’m trying to connect to an Atlas cluster via tunneling through a bastion host (since I’m executing code from Pipedream which launches from a non-static set of IPs so I can’t know which to whitelist unless I use my own bastion server).

Using node.js packages, I’m running this code below wrapped in an async function, but it seems to not be able to connect to the MongoDB Atlas cluster through the tunnel. I’ve verified that the tunnel actually works for various other purposes. I’m using the ssh package “ssh2-promise”, and have also tried “tunnel-ssh”. If I don’t use tunneling and just connect the driver straight to the cluster via the +SRV name or the explicit standard connection string, it’ll work (with 0.0.0.0/0 access allowed, of course). But I really want to get this tunnel working. What am I doing wrong here?

const SSH2Promise = require('ssh2-promise');
const MongoClient = require('mongodb').MongoClient

const database = "<database name>";
const mongoUsername = auths.mongodb.username;
const mongoPassword = auths.mongodb.password;

const { 
  host, 
  port,
  username, 
  privateKey,
} = auths.ssh

const ssh = new SSH2Promise({
  host,
  username,
  privateKey,
})

const tunnel1 = await ssh.addTunnel({
  remoteAddr: "<shard00>.55gfk.mongodb.net", 
  remotePort: 27017,
  localHost: "127.0.0.1"
})

const tunnel2 = await ssh.addTunnel({
  remoteAddr: "<shard01>.55gfk.mongodb.net", 
  remotePort: 27017,
  localHost: "127.0.0.1"
})

const tunnel3 = await ssh.addTunnel({
  remoteAddr: "<shard02>.55gfk.mongodb.net", 
  remotePort: 27017,
  localHost: "127.0.0.1"
})

console.log("tunnel established");

const url = `mongodb://${mongoUsername}:${mongoPassword}@${tunnel1.localHost}:${tunnel1.localPort},${tunnel2.localHost}:${tunnel2.localPort},${tunnel3.localHost}:${tunnel3.localPort}/${database}?ssl=true&replicaSet=atlas-<cluster>-shard-0&authSource=admin&retryWrites=true&w=majority`

console.log(url)

const client = await MongoClient.connect(url, { 
  useNewUrlParser: true, 
  useUnifiedTopology: true 
});

console.log("db connection established");

client.close();
ssh.close();

Hi! Did you find a solution?

Nope. I’ve resigned to just making really secure credentials and allowing 0.0.0.0/0 for now until Pipedream can NAT out its compute somehow to a static IP.