几天来,我一直在尝试在node.js中创建ssh隧道,但一直没有成功。
我是个新手,所以我希望你能容忍我。
我正试图访问aws中托管的数据库,制作该数据库的程序员给我发了一封电子邮件,其中包含以下数据以进行连接:
SSH隧道
ssh-N-L 33306:justoaca-db-prod.ciengjumlrqb.us-east-1.rds.amazonaws.com:3306
[email protected]
-i~/.ssh/Justoaa-db-bridge.pem
用户数据库
Justoaarea/XXXXXXXXXX
pem密钥附在带有密码的zip中,我将zip密码单独发送给Javier。
问题是,只要我从vs终端或windows命令提示符创建隧道,ssh隧道就可以完美地工作(能够检索数据库的任何表)。
但是,当我想从node.js创建它时,或者我一直在加载,直到它因超过连接尝试的时间限制而断开连接,或者它没有直接连接。
我在代码下面留下(我一直在导入许多模块,并尝试不同的方法,但没有成功)。
const mysql = require("mysql");
const { exec } = require('child_process');
const path = require('path');
const os = require('os');
var Client = require('ssh2').Client;
const { readFileSync } = require('fs');
class dbReadOnly {
constructor() {
this.dbConfig = {
host: "127.0.0.1",
port: 33306, // here I tried with port 22 and 3306
user: "justoacaread",
password: "XXXXXX",
database: "justoaca",
};
this.tunnel = null;
}
connect(callback) {
let sshConfig = {
username: "ec2-user",
host: "3.209.213.83",
port: 33306, //tried here with 3306 and 22 too.
privateKey: readFileSync("./certificates/Justoaca-db-bridge.pem"),
};
console.log("Connecting...");
const conn = new Client();
conn.on('ready', () => {
console.log("SSH connection established.");
// Establish SSH tunnel to the remote database
conn.forwardOut(
// Source: Local IP and port for forwarding
'127.0.0.1',
33306,
// Destination: IP and port of the remote database
'justoaca-db-prod.ciengjumlrqb.us-east-1.rds.amazonaws.com',
3306,
(err, stream) => {
if (err) {
console.error('Error establishing SSH tunnel:', err);
callback(err);
return;
}
console.log('SSH tunnel established successfully.');
// Create a database connection using the SSH tunnel stream
const dbConnection = mysql.createConnection({
host: '127.0.0.1',
port: 33306,
user: 'justoacaread',
password: 'XXXXXXXX',
database: 'justoaca',
stream: stream, // Pass the SSH tunnel stream as the communication channel
});
dbConnection.connect((err) => {
if (err) {
console.error('Error connecting to the database:', err);
callback(err);
return;
}
console.log('Connected to the database successfully.');
callback(null, dbConnection);
});
}
);
})
.on('error', (err) => {
console.error('Error in SSH connection:', err);
callback(err);
})
.connect(sshConfig);
}
async query(sql) {
console.log("Executing query");
return new Promise((resolve, reject) => {
this.connection.query(sql, (error, results) => {
if (error) {
console.error("Error executing the query:", error);
reject(error);
} else {
console.log("Resolving query results");
resolve(results);
}
});
});
}
async disconnect() {
console.log("DISCONNECTING!");
//This method was used when i tried to create the ssh with the exec command from the module child_process
// Command to stop the SSH tunnel process
let killCommand;
if (os.platform() === 'win32') {
// Windows
killCommand = 'taskkill /IM "ssh.exe" /F';
} else {
// Other Unix-based systems
killCommand = 'pkill -f "ssh -N -L 33306:justoaca-db-prod.ciengjumlrqb.us-east-1.rds.amazonaws.com:3306"';
}
await exec(killCommand, (error, stdout, stderr) => {
if (error) {
console.error('Error executing the SSH disconnect command:', error);
return;
}
// The command executed successfully
console.log('SSH disconnect command executed successfully.');
console.log('Output:', stdout);
});
this.connection.end();
if (this.tunnel) {
this.tunnel = null;
}
}
}
module.exports = new dbReadOnly();
我最接近的一次是尝试使用child_process模块中的exec方法。
重要的方法是connect,看起来是这样的:
async connect() {
console.log("connecting...")
const command = 'ssh -vvv -N -L 33306:justoaca-db-prod.ciengjumlrqb.us-east-1.rds.amazonaws.com:3306 [email protected] -i ./certificates/Justoaca-db-bridge.pem';
await exec(command, (error, stdout, stderr) => {
if (error) {
console.error('Error executing SSH:', error);
return;
}
});
}
左边是使用子进程exec的终端调试,右边是使用终端直接命令的终端调试(它有效)
奇怪的是,有时它是有效的。它从node.js中检索表。但当我从一个新的终端重试时,它会中断。有时它能工作一段时间,有时它永远不会工作,而且我不会修改代码或任何东西。我不知道为什么会这样。
所以在简历中,请帮我创建这个隧道。我已经花了好几天的时间试图解决这个问题,但都无济于事。
我已尝试使用所有ssh模块。
当我将ssh方法包装在promise中时,它总是会中断(保持加载直到断开连接)。
此外,如果我不把它包装在承诺中,它就根本没有联系。