Skip to content

Instantly share code, notes, and snippets.

@hjzheng
Created September 7, 2019 06:12
Show Gist options
  • Save hjzheng/c7826e9e4da1a8e45f9fdd25d49220fa to your computer and use it in GitHub Desktop.
Save hjzheng/c7826e9e4da1a8e45f9fdd25d49220fa to your computer and use it in GitHub Desktop.
ssh 端口转发到 mysql
const mysql = require('mysql2')
const tunnel = require('tunnel-ssh')
const ssh2mysql = {
_conn: null,
_mysql_pool: null,
/**
* @param obj sshConfig SSH Configuration as defined by ssh2 package
* @param obj dbConfig MySQL Configuration as defined by mysql(2) package
* @return Promise
*/
connect: function(sshConfig, dbConfig) {
dbConfig = ssh2mysql._addDefaultsDBConfig(dbConfig)
sshConfig = ssh2mysql._addDefaultsSSHConfig(sshConfig)
return new Promise(function(resolve, reject) {
ssh2mysql._conn = new tunnel(sshConfig, (error, tnl) => {
if (error) {
ssh2mysql.close()
var msg =
error.reason == 'CONNECT_FAILED' ? 'Connection failed.' : error
return reject(msg)
}
ssh2mysql._mysql_pool = mysql.createPool(dbConfig)
const execSql = sql => {
return new Promise((resolve, reject) => {
ssh2mysql._mysql_pool.getConnection(function(err, conn) {
if (err) {
reject(err)
ssh2mysql._mysql_pool.releaseConnection(conn)
}
conn.query(sql, (error, results) => {
if (error) {
reject(error)
} else {
resolve(results)
}
ssh2mysql._mysql_pool.releaseConnection(conn)
})
})
})
}
resolve({ execSql })
})
})
},
close: function() {
if ('end' in ssh2mysql._mysql_pool) {
ssh2mysql._mysql_pool.end(() => {})
}
if ('end' in ssh2mysql._conn) {
ssh2mysql._conn.end()
}
},
_addDefaultsSSHConfig(sshConfig) {
return Object.assign(
{ keepAlive: true, localHost: '127.0.0.1', localPort: 12345, port: 22 },
sshConfig,
)
},
_addDefaultsDBConfig(dbConfig) {
return Object.assign({ host: 'localhost', port: 3306 }, dbConfig)
},
}
export default ssh2mysql
@hjzheng
Copy link
Author

hjzheng commented Sep 7, 2019

"externalDB": {
    "type": "mysql",
    "host": "10.0.1.57",
    "port": 3306,
    "username": "xxxx",
    "password": "passwd",
    "database": "db"
  },
  "ssh": {
    "username": "root",
    "host": "10.0.1.60",
    "port": 22,
    "dstHost": "10.0.1.57",
    "dstPort": 3306,
    "localHost": "127.0.0.1",
    "localPort": 12345,
    "privateKey": "/Users/hjzheng/.ssh/id_rsa"
  }

how to use:

import ssh2mysql from './ssh2mysql'
import { config } from '@ys/api'

const fs = require('fs')
const dbConf = config.externalDB
const sshConf = config.ssh

let mysql

const execSql = async (sql: string) => {
  if (!mysql) {
    mysql = await ssh2mysql.connect(
      {
        ...sshConf,
        privateKey: fs.readFileSync(sshConf.privateKey),
      },
      { ...dbConf, user: dbConf.username },
    )
  }
  return mysql.execSql(sql)
}

export default execSql

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment