Node.js 通过 ssh 连接

问题描述 投票:0回答:2

我有一个可用的 node.js 服务器,但需要为 ssh 连接设置:

var mysql = require('mysql')
var io = require('socket.io').listen(3000)
var db = mysql.createConnection({

    host: 'hostname',
    user: 'username',
    password: '12345',
    database: '12345',
    port: 3306,
    socket: '/var/run/mysqld/mysqld.sock' 
})

db.connect(function(err){
    if (err) console.log(err)
})

我知道有用于此目的的 ssh npm 库,但是可用的选项(ssh2、node-sshclient 等)似乎处理了可能使事情过于复杂的相当复杂的功能。我正在寻找通过 ssh 连接到我的 mysql 数据库的最简单方法。实现此目标的最佳方法是什么?

mysql node.js ssh
2个回答
35
投票

如果您运行的是 linux/unix 系统,请执行以下操作:

通过

ssh
连接到您的 mysql 服务器并通过此 ssh 隧道代理 mysql 端口(默认为 3306)。

工作原理如下:

1 输入

screen
(启动屏幕会话,即使外壳关闭也是永久性的)。

2 在屏幕外壳中键入:

ssh -L 3306:127.0.0.1:3306 your_servers_domain_or_ip -lyour_login_name

3 输入您的 ssh 密码/或使用 PKI 身份验证以避免手动步骤

4 完成...现在可以连接 MySQL,就像它与您的应用程序安装在同一台机器上一样。

从 node.js 连接到 MySQL,如下所示:

var db = mysql.createConnection({
    host: '127.0.0.1', // Important to connect to localhost after connecting via ssh in screen
    user: 'username',
    password: '12345',
    database: '12345',
    port: 3306
});

0
投票

有时最好动态地(在代码中)实例化 SSH 隧道连接,而不是单独使用操作系统库。例如,它可以更轻松地自动关闭连接、与其他开发人员共享环境或根据环境有条件地使用 SSH 隧道。

使用 tunnel-ssh 等软件包,这很容易。基于所提供的示例,连接代码如下所示:

import { createSSHTunnel } from "./sshTunnel";

const { srcAddr, srcPort } = await createSSHTunnel();

var db = mysql.createConnection({
    host: srcAddr,
    port: srcPort,
    user: 'username',
    password: '12345',
    database: '12345'  
});

sshTunnel
模块中完全抽象出所有逻辑,它看起来像:

// sshTunnel.js

import { createTunnel } from "tunnel-ssh";

export async function createSSHTunnel(srcAddr = "127.0.0.1", srcPort = 12345) {
  const tunnelOptions = {
    autoClose: true,
  };
  const serverOptions = {
    port: srcPort,
  };
  const sshOptions = {
    host: process.env.SSH_HOST,
    port: parseInt(process.env.SSH_PORT),
    username: process.env.SSH_TUNNEL_USER,
    password: process.env.SSH_TUNNEL_PASSWORD,
  };
  const forwardOptions = {
    srcAddr: srcAddr,
    srcPort: srcPort,
    dstAddr: process.env.DB_HOST,
    dstPort: parseInt(process.env.DB_PORT),
  };
  try {
    await createTunnel(
      tunnelOptions,
      serverOptions,
      sshOptions,
      forwardOptions
    );
  } catch (error) {
    if (error.code === "EADDRINUSE") {
      // Assume port is uniquely used by SSH tunnel, so existing connection can be reused
      console.log(`Returning existing SSH tunnel on ${srcAddr}:${srcPort}.`);
      return { srcAddr, srcPort };
    } else {
      throw error;
    }
  }
  console.log(`SSH tunnel successfully created on ${srcAddr}:${srcPort}.`);
  return { srcAddr, srcPort };
}

备注:

  • SSH隧道任意使用本地端口12345
  • 涉及的环境变量有:
    • DB_HOST
      :数据库主机名
    • DB_PORT
      :数据库端口,原始MySQL示例中为3306,Postgres等为5432
    • SSH_HOST
      :服务 SSH 隧道的机器的主机名
    • SSH_PORT
      :服务 SSH 隧道的机器端口
    • SSH_TUNNEL_USER
      :SSH 隧道的用户名
    • SSH_TUNNEL_PASSWORD
      :SSH隧道的密码
© www.soinside.com 2019 - 2024. All rights reserved.