Windows开发笔记本如何通过SSH隧道用Node.js访问受限MySQL实例?
问题:开发笔记本通过Node.js连接受白名单限制的MySQL实例
环境配置
- MySQL实例:仅允许白名单内IP通过IP/用户名/密码连接,无操作系统/SSH访问权限
- 授权服务器:拥有root权限,已在MySQL实例白名单中,可通过
mysql -h <MySQL实例IP> -u <用户名> -p命令连接MySQL实例 - 开发笔记本:Windows系统,动态DHCP无法加入白名单,可SSH连接至授权服务器
(注:以上架构为IT部门固定配置,无法修改)
当前情况
- 已在DBeaver中配置SSH隧道,可通过授权服务器成功连接MySQL实例
- 在Windows的Git Bash中执行
ssh -L 3306:localhost:3306 Authorized_Server连接授权服务器,但未实现预期效果
解决方案
方法一:手动建立正确的SSH隧道
你之前的SSH隧道命令逻辑有误——需要将本地端口转发到MySQL实例的IP和端口,而非授权服务器的localhost(授权服务器的localhost指向自身,不是目标MySQL实例)。执行以下命令:
ssh -L 3306:<MySQL实例IP>:3306 <授权服务器用户名>@<授权服务器IP>
示例(假设MySQL实例IP为192.168.1.100,授权服务器IP为10.0.0.5,用户名为root):
ssh -L 3306:192.168.1.100:3306 root@10.0.0.5
保持该SSH连接窗口打开,随后在Node.js代码中连接本地3306端口即可:
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', port: 3306, user: '<MySQL用户名>', password: '<MySQL密码>', database: '<目标数据库名>' }); connection.connect((err) => { if (err) throw err; console.log('成功连接到MySQL实例'); // 执行查询示例 connection.query('SELECT 1 + 1 AS solution', (err, results) => { if (err) throw err; console.log('查询结果:', results[0].solution); connection.end(); }); });
方法二:在Node.js代码中直接集成SSH隧道
无需手动维护SSH连接,使用tunnel-ssh包在代码中自动建立隧道。
- 安装依赖:
npm install mysql2 tunnel-ssh
- 编写代码:
const mysql = require('mysql2'); const tunnel = require('tunnel-ssh'); // SSH隧道配置 const sshConfig = { host: '<授权服务器IP>', port: 22, username: '<授权服务器用户名>', password: '<授权服务器密码>' // 也可使用密钥认证:privateKey: require('fs').readFileSync('本地私钥路径') }; // MySQL连接配置 const mysqlConfig = { host: '<MySQL实例IP>', port: 3306, user: '<MySQL用户名>', password: '<MySQL密码>', database: '<目标数据库名>' }; // 建立SSH隧道并连接MySQL tunnel({ ...sshConfig, dstHost: mysqlConfig.host, dstPort: mysqlConfig.port, localHost: '127.0.0.1', localPort: 3307 // 自定义本地端口,避免与其他服务冲突 }, (error, server) => { if (error) throw error; const connection = mysql.createConnection({ ...mysqlConfig, host: '127.0.0.1', port: 3307 }); connection.connect((err) => { if (err) throw err; console.log('通过SSH隧道成功连接MySQL'); // 执行查询示例 connection.query('SELECT NOW() AS current_time', (err, results) => { if (err) throw err; console.log('当前数据库时间:', results[0].current_time); connection.end(); server.close(); // 操作完成后关闭隧道 }); }); });
内容的提问来源于stack exchange,提问作者EpiX
相关产品推荐
相关产品推荐

