navicat 17 不支持双层 ssh 隧道,因其 ssh 页面仅接受单组参数,无法配置 proxyjump 或解析多跳规则;必须用本地 ssh 命令(如 ssh -j 或嵌套 -l)预先建立双跳端口映射,再让 navicat 连接 localhost:映射端口,且需确保数据库授权匹配跳板机 b 的内网 ip。

Navicat 17 不支持原生配置两层 SSH 隧道(即跳板机 A → 跳板机 B → 数据库)。它只提供单层 SSH 隧道能力,所有“双跳”需求必须由本地系统 SSH 客户端提前建立好端口映射,再让 Navicat 连这个本地映射端口。
为什么 Navicat 的 SSH 页面填不了第二台跳板机
Navicat 的 SSH 选项卡只接受一组 SSH 连接参数:主机、端口、用户名、认证方式。它不会执行 ssh -J 或嵌套 ProxyJump,也不解析 ~/.ssh/config 中的多跳规则。你填进去的任何“第二跳地址”都会被当作第一跳目标直连,必然失败。
- 填两个 SSH 主机?
SSH页面只有一个“主机”输入框,无法分层 - 填
127.0.0.1:2222想复用已建隧道?Navicat 不会自动识别或复用本地 SSH 进程,它只自己发起新连接 - 用公钥认证时私钥格式不对(比如 OpenSSH 的
id_rsa直接拖进去)?Windows 下 Navicat 仅认.ppk,不转就报Authentication failed
正确做法:用本地 ssh 命令搭好双跳隧道,Navicat 只连 localhost
核心思路是把“跳板机 A → 跳板机 B → 数据库”这整条链路,压缩成一个本地端口(比如 13306),然后 Navicat 当作普通本地 MySQL 来连。
- 先确保本地能通过命令行完成双跳:
ssh -J userA@jump-a.example.com userB@jump-b.internal -L 13306:10.10.5.20:3306 -N - 若
-J不可用(老版本 OpenSSH),改用两层-L:
①ssh -L 2222:jump-b.internal:22 userA@jump-a.example.com -N
② 新终端运行:ssh -L 13306:10.10.5.20:3306 -p 2222 userB@127.0.0.1 -N - 隧道建立后,Navicat 的
常规页中:主机填127.0.0.1,端口填你映射的本地端口(如13306) -
SSH页必须 完全禁用(不勾选“使用SSH隧道”),否则 Navicat 会试图再起一层隧道,和你手动建的冲突
MySQL 权限必须授权给跳板机 B 的内网 IP
从 Navicat 看,流量路径是:本地 → jump-a → jump-b → 数据库,但数据库看到的客户端 IP 是 jump-b 的内网地址(比如 10.10.5.100),不是 jump-a 也不是你的本地 IP。
- 执行
SELECT User, Host FROM mysql.user;,确认目标用户绑定的是 jump-b 的 IP,例如'app'@'10.10.5.100' -
'app'@'%'在某些云厂商或启用了skip-name-resolve的 MySQL 上可能不生效,别依赖它 - 如果 jump-b 的 IP 不固定,授权子网更稳妥:
'app'@'10.10.5.%' - 检查 jump-b 是否能通数据库:
telnet 10.10.5.20 3306(在 jump-b 上执行),不通说明网络或防火墙阻断,隧道再完美也白搭
连接频繁中断?不是 Navicat 的锅,是 SSH 链路被静默回收
双跳隧道比单跳更容易断,因为中间经过更多 NAT、安全组、跳板机 sshd 配置。现象是:刚连上正常,闲置 2–3 分钟后卡死、报 Lost connection to MySQL server 或 Connection reset。
- 在本地
~/.ssh/config中为跳板机加保活:Host jump-a.example.comServerAliveInterval 45ServerAliveCountMax 3 - jump-b 的
/etc/ssh/sshd_config也要配:TCPKeepAlive yes、ClientAliveInterval 60 - Navicat 自身的“保持连接”设置(如“每 30 秒发送 ping”)只作用于 MySQL 协议层,对底层 SSH 隧道无效
真正难的从来不是 Navicat 怎么点,而是搞清每一跳的网络视角、权限归属和保活责任落在哪一层。跳板机数量每+1,排查路径就指数级变长——别跳过在每台跳板机上手动 telnet 和 mysql -h 验证这一步。











