SSH隧道连MySQL失败主因是端口转发配置错误或MySQL权限未授权给跳板机IP;需用-L指定内网DB真实IP、本地连接用127.0.0.1、授权用户绑定跳板机IP或子网,并配置KeepAlive保活。
SSH隧道连MySQL连不上?先检查端口转发是否生效
本地连不上远程mysql,大概率是ssh隧道没通,而不是mysql本身拒绝连接。关键看ssh命令里有没有正确启用本地端口转发(-l),且目标地址写的是跳板机能访问的内网地址,不是127.0.0.1——跳板机上的127.0.0.1指向它自己,不是目标db。
- 正确写法:
ssh -L 3307:10.10.5.20:3306 user@jump-host(10.10.5.20是DB在内网的真实IP) - 错误写法:
ssh -L 3307:127.0.0.1:3306 user@jump-host(除非MySQL真装在跳板机上) - 连通后,在本地用
mysql -h 127.0.0.1 -P 3307 -u dbuser -p测试,注意必须用127.0.0.1而非localhost,否则会走socket文件跳过TCP - 如果
ssh命令返回就退出,说明连接被立即断开,检查跳板机/etc/ssh/sshd_config中AllowTcpForwarding yes是否开启
MySQL报错“Access denied for user”但密码没错?权限绑定的是IP不是隧道出口
MySQL用户权限是按来源IP校验的,你本地发起的连接,经SSH隧道后,对MySQL来说来源IP是跳板机的内网IP(比如10.10.5.100),不是你的笔记本IP。所以CREATE USER 'foo'@'localhost'或'%' 都不管用。
- 必须显式授权给跳板机IP:
CREATE USER 'foo'@'10.10.5.100' IDENTIFIED BY 'xxx'; - 或者更稳妥:授权给跳板机所在子网,如
'foo'@'10.10.5.%',避免每次换跳板机都要改 - 别漏掉
GRANT和FLUSH PRIVILEGES,只建用户不赋权照样连不上 - 如果MySQL启用了
skip-name-resolve,就别用主机名授权(如'foo'@'jump-prod'),DNS解析失败会导致权限匹配失败
连接卡住、超时或中断频繁?调整SSH KeepAlive参数
SSH连接空闲几分钟后被防火墙或中间设备静默断开,但本地MySQL客户端不知道,还在等响应,表现就是卡死或Lost connection to MySQL server。这不是MySQL问题,是隧道链路维持不住。
- 服务端(跳板机)加配置:
sudo echo "ClientAliveInterval 60" >> /etc/ssh/sshd_config,再sudo systemctl restart sshd - 客户端加配置(~/.ssh/config):
Host jump-host HostName jump.example.com User deploy ServerAliveInterval 45 ServerAliveCountMax 3 -
ServerAliveInterval 45表示每45秒发一次保活包,ServerAliveCountMax 3代表连续3次无响应才断开,这样最多容忍约2分钟断连 - 别把
ServerAliveInterval设太小(如5秒),可能触发某些网络设备限流
为什么不用ProxyCommand而坚持用-L?安全边界和运维习惯问题
ProxyCommand确实能实现免本地端口占用的直连(如mysql -h db-internal -p --protocol=TCP),但它要求本地ssh能直接执行跳板机命令,意味着跳板机必须开放nc或socat,且MySQL服务器要允许跳板机IP直连——这其实扩大了攻击面。生产环境更倾向显式端口转发。
-
-L方式下,MySQL只对跳板机IP开放,本地机器即使中毒也不会暴露DB真实地址 - 所有流量经
ssh加密,且可配合ExitOnForwardFailure yes确保隧道建立失败时ssh不后台运行 - 监控和审计更清晰:跳板机上
netstat -tunlp | grep :3306能看到谁在转发,而ProxyCommand的连接在MySQL侧显示为跳板机本机连接,溯源困难 - 如果非要用
ProxyCommand,务必确认跳板机/etc/ssh/sshd_config中PermitOpen未限制目标端口,否则会被拒绝
真正麻烦的不是建隧道,而是每次变更跳板机、DB地址或网络策略时,得同步更新三处:SSH配置、MySQL用户授权、以及开发文档里的连接说明——漏掉任何一处,故障就来了。

















