通过SSH隧道连接服务器上的MySQL

在自己的电脑查看服务器 MySQL 时,可以先连接 SSH,再把本机的一个端口转到数据库。下面只让隧道监听 127.0.0.1,数据库端口不需要因此对公网开放。适用于 Linux 服务器上的 MySQL 8.0.18 及以后版本、MySQL 8.4,以及带 OpenSSH 的 Windows、macOS 或 Linux 客户端。

先确认服务器本机能够连接数据库

准备当前服务器 IP、实际 SSH 端口、能正常登录的 SSH 账户,以及目标数据库的专用账号。这两组账号用途不同。示例 203.0.113.10 是文档地址,baole_admin、baole_reader 和 baole_site 都要替换成自己的信息。

没有合适的数据库账号时,由数据库管理员在 MySQL 内为这次只读检查创建独立账号:

CREATE USER 'baole_reader'@'127.0.0.1' IDENTIFIED BY RANDOM PASSWORD;

创建成功会显示生成的密码,立即保存到自己的密码管理器,不截图公开。若提示账号已经存在,就停止核对,不继续授权或重置。确认新账号创建成功后,只授予目标库的读取权限:

GRANT SELECT ON baole_site.* TO 'baole_reader'@'127.0.0.1';
SHOW GRANTS FOR 'baole_reader'@'127.0.0.1';

需要写入或修改结构的工作应另按实际任务授权,本文的只读账号不会获得这些权限。

先在服务器终端使用该账号做一次 TCP 连接。以下示例要求实例已支持 MySQL TLS,保留加密连接;如有自己的 CA 和证书校验要求,沿用已有参数。

mysql --protocol=TCP --ssl-mode=REQUIRED -h 127.0.0.1 -P 3306 -u baole_reader -p baole_site
SELECT @@hostname, @@port, DATABASE(), CURRENT_USER();
SHOW SESSION STATUS LIKE 'Ssl_cipher';
exit

应进入目标库,CURRENT_USER() 显示实际匹配的数据库账号,Ssl_cipher 有值。这里尚不能连接时,先按 MySQL连接失败排查 处理监听、账号及 TLS;SSH 隧道不会修复数据库本机认证问题。

在自己的电脑建立隧道

打开本地终端或 PowerShell,沿用已经验证过的 SSH 登录方式,执行下面这一整行。-p 22 是 SSH 端口;最后的 3306 是从服务器本机访问数据库的端口。

ssh -N -T -L 127.0.0.1:13306:127.0.0.1:3306 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -p 22 baole_admin@203.0.113.10

第一次连接先核对 SSH 主机指纹;密钥登录可继续使用原有密钥配置。登录后窗口没有出现服务器命令提示符是正常现象:-N 表示只转发,不执行远程命令。保持窗口打开。

这一段 对应位置
127.0.0.1:13306 你自己电脑上的入口,只接受本机连接。
后面的 127.0.0.1:3306 由 SSH 服务器去访问的目标。这里的 127.0.0.1 指服务器自己。
baole_admin@203.0.113.10 SSH 登录账户和服务器地址,不是 MySQL 账号。

如果数据库位于另一台内网主机,后半段地址及数据库授权需要按实际拓扑单独配置,不能直接套用本篇的本机示例。

连接本机13306,确认最终到的是远端数据库

另开一个本地终端,使用支持该 MySQL 版本的客户端:

mysql --protocol=TCP --ssl-mode=REQUIRED -h 127.0.0.1 -P 13306 -u baole_reader -p baole_site

再次执行前面的身份查询,结果应与服务器本机检查一致。这里 @@port 通常仍显示数据库实际端口 3306;本地 13306 只是转发入口。随后执行 SHOW TABLES;,并读取一条有权限查看的业务记录。只看到本机端口打开,还不能证明数据库账号和查询都正常。

使用图形化数据库客户端时,主机填 127.0.0.1、端口填 13306,再填数据库账号、密码和库名,保留对应 TLS 设置。已经在终端建好隧道,就使用普通 TCP 连接模式;不要再同时启用软件里的另一套 SSH 隧道。

连接失败时看哪一层

提示或现象 处理方向
Address already in use 本地13306被占用。把命令中的本地端口改为13307,并同步改数据库客户端端口。
administratively prohibited SSH账号或服务策略未允许这类转发。让管理员核对该账号的转发范围,不直接放开所有目的地址。
connect failed: Connection refused SSH已连接,但服务器不能访问目标数据库端口。回到第一步检查实际监听地址和端口。
Access denied、TLS或认证插件报错 数据库已收到连接。核对数据库账号、来源匹配、当前客户端与TLS配置,不把网站密码填进数据库。

ExitOnForwardFailure 能发现隧道监听创建失败,但不会把后续每次数据库连接失败都变成 SSH 退出。使用结束先断开数据库客户端,再在隧道窗口按 Ctrl+C;随后新建到本地13306的连接应失败。临时数据库账号不再使用时,再由管理员按其实际依赖回收。