如何使用Node.js建立到MongoDB数据库的SSH隧道连接

of1yzvn4  于 2023-04-20  发布在  Go
关注(0)|答案(5)|浏览(269)

我的凭据与Robomongo配合良好,但我无法与node.js建立连接
我尝试使用ssh 2和tunnel-ssh npm模块建立连接,但两次都失败了。

  • mongo连接不需要密码
  • ssh连接是用pem键建立的
    这是我在ssh 2模块中使用的代码,我可以正确地建立隧道,但mongo连接失败
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
});

代码为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);
        });

    });
});

我不确定是在建立隧道后使用常规的MongoDB连接字符串,还是将数据库引用为localhost,例如
mongodb://localhost:portnumber.

mongodb:databasepath.subpath.mongodbdns.com:27000
Localhost给我一个权限拒绝错误,后者给我一个超时

egmofgnx

egmofgnx1#

正如mscdex提到的,ssh 2不是一个很好的模块,不能用来建立到数据库的ssh隧道连接。tunnel-ssh更合适。
以下是我使用的配置选项:
dstPort:远程数据库连接端口
localPort:与dstPort相同,它将是用于本地机器的端口
用户名:SSH用户名,
主机:SSH地址
dstHost:数据库连接url(...mongodbns.com),
privateKey:SSH密钥
然后,一旦你的隧道连接通过mongoose连接到你的localhost,如mondodb://localhost:27000(使用localPort中定义的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
}
xtupzzrd

xtupzzrd2#

由于mongoose不支持传入流作为底层连接,因此您必须侦听本地端口(例如27000),并通过ssh连接将传入连接转发到该端口。
幸运的是,存在构建在ssh2上的第三方模块,可以为您提供这种功能,例如tunnel-ssh

liwlm1x9

liwlm1x93#

您可以使用node的官方mongodb客户端来实现

const sshTunnelConfig = {
  agent: process.env.SSH_AUTH_SOCK,
  username: 'ec2-user',
  privateKey: require('fs').readFileSync('./path-to-ec2-key.pem'),
  host: '3.98.174.12', //IP adress of VPS which is the SSH server
  port: 22,
  dstHost: 'docdb-cluster-vmabwxueb51y.eu-central-1.docdb.amazonaws.com',
  dstPort: 27017,
  localHost: '127.0.0.1',
  localPort: 27018 //or anything else unused you want
};

const connectionProperties = {
  sslValidate: true,
  ssl: true,
  sslCA: [fs.readFileSync('rds-combined-ca-bundle.pem')],
  useNewUrlParser: true,
  useUnifiedTopology: true,
  authMechanism: 'SCRAM-SHA-1',
  auth: {
    user: 'docdbuser',
    password: '<PASSWORD>'
  },
  tlsAllowInvalidHostnames: true,
  tlsAllowInvalidCertificates: true,
};

tunnel(sshTunnelConfig, async (error, server) => {
  if (error) {
    console.log('SSH connection error: ', error);
  }
  
   const MongoClient = require('mongodb').MongoClient;
   const client = MongoClient.connect('mongodb://localhost:27018/', propertiesConnection,
    function(err, client) {
      if(err)
        throw err;

      //Specify the database to be used
      db = client.db('database-name');

      //Specify the collection to be used
      col = db.collection('collection-name');

      //Insert a single document
      col.insertOne({'hello':'Amazon DocumentDB'}, function(err, result){
        //Find the document that was previously written
        col.findOne({'hello':'Amazon DocumentDB'}, function(err, result){
          //Print the result to the screen
          console.log(result);

          //Close the connection
          client.close()
        });
      });
    });
  
});
6qqygrtg

6qqygrtg5#

由于某些原因,上面的所有答案对我都不起作用,我发布了对我有用的代码。我正在从我的Nodejs web服务器隧道到在线ubuntu vm上的PostgreSQL数据库:

const SSH2Promise = require('ssh2-promise');
const {Client } = require('pg');

let config = {
    host:process.env.SSH_HOST, //your machine IP-address like [193.xxx.xx.xxx]
    port:process.env.SSH_PORT, //port you ssh to, probably 22
    username: process.env.SSH_USERNAME, //username of your machine
    privateKey: fs.readFileSync(path.join(__dirname, "../" + process.env.PRIVATE_KEY)) //your ssh private key to log in
};

function getDBConfig(port) {

    return new Client({
        user: process.env.DB_USER,
        host: process.env.DB_HOST,
        database: process.env.DB_NAME,
        password: process.env.DB_PASS,
        port: port,
    });
}

async function makeDb(port) {
    let dbClient = getDBConfig(port);
    await dbClient.connect();
    return {
        async query(sql) {
            return (await dbClient.query(sql)).rows;
        }
    };
}

const sshConn = new SSH2Promise(config);
let con;
(async function(){
    await sshConn.connect();
    console.log("Connection established");
    let tunnel = await sshConn.addTunnel({remoteAddr: process.env.REMOTE_HOST, remotePort: process.env.REMOTE_PORT});
//Remote host: just use 127.0.0.1
//Remote port: port where your db is connected to ex: 5432
    con = await makeDb(tunnel.localPort);
})();

//use connection like this:
await con.query("SELECT ... sql statement here);

相关问题