navicat通过ssh隧道连接mysql报“access denied”时,根本原因是mysql服务端认证不通过:①用户未授权给'localhost'(ssh隧道使mysql视连接来源为本机);②mysql 8.0+的caching_sha2_password插件与旧版navicat不兼容;③bind-address未包含127.0.0.1或skip-networking被启用;④navicat连接设置中host误填为localhost(应填127.0.0.1以走tcp隧道)。
navicat ssh隧道连通但mysql报“access denied”
ssh连接成功只说明跳转通道建好了,不代表mysql服务本身接受这个通道过来的连接。最常被忽略的一点是:mysql.user 表里没有为 localhost(注意不是127.0.0.1)授权的用户记录。
SSH隧道下,MySQL看到的客户端来源是本机(即数据库服务器自身),所以它查的是 user@localhost 这条记录,而不是 user@'192.168.x.x' 或 user@'%'。
- 执行
SELECT user, host FROM mysql.user WHERE user = 'your_user';,确认是否存在host = 'localhost'的行 - 若只有
host = '%'或'192.168.1.100',即使SSH隧道走通,MySQL仍会拒绝认证 - 补一条:
CREATE USER 'your_user'@'localhost' IDENTIFIED BY 'your_password';,再GRANT ... ON *.* TO 'your_user'@'localhost'; - 别漏掉
FLUSH PRIVILEGES;
MySQL 8.0+ 的 caching_sha2_password 导致 SSH 隧道连接失败
SSH隧道不改变认证插件逻辑。如果 MySQL 8.0+ 用户用的是 caching_sha2_password,而 Navicat 版本低于 16.0.18,就会在隧道内也触发认证失败——错误码仍是 1045,但原因不是密码错,而是插件不兼容。
- 检查插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user'; - 若
plugin是caching_sha2_password,且你无法升级 Navicat,就改回兼容模式:ALTER USER 'your_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 注意:改完后必须重连,旧连接不会自动切换认证方式
bind-address 和 skip-networking 对 SSH 隧道的影响
很多人以为 SSH 隧道绕过了网络层限制,其实不然。MySQL 仍要监听并接收来自本机(127.0.0.1 或 ::1)的 TCP 连接,而这条连接是由 SSH 进程代为发起的。所以 bind-address 必须包含 127.0.0.1 或设为 0.0.0.0;skip-networking=ON 会直接禁用所有 TCP 连接,SSH 隧道也会失效。
- 检查配置:
mysqld --verbose --help | grep bind-address,或看my.cnf中[mysqld]段 - 合法值包括:
127.0.0.1、0.0.0.0、::1;127.0.0.1就够用,不必开0.0.0.0 - 确认
skip-networking未启用(默认是 OFF,但手动配过就可能 ON) - 改完配置必须重启 MySQL 服务,
systemctl restart mysqld或 Windows 服务管理器
Navicat 连接设置里 Host 填 127.0.0.1 还是 localhost?
在 SSH 隧道场景下,必须填 127.0.0.1。因为 localhost 在 MySQL 客户端协议中会强制走 Unix socket(即使开了 TCP),而 SSH 隧道只能转发 TCP 流量,socket 文件根本不可达。
- 填
localhost→ Navicat 尝试连/tmp/mysql.sock→ 失败(文件不存在于本地,也不在远程) - 填
127.0.0.1→ Navicat 发起 TCP 连接 → SSH 隧道捕获并转发到远程 MySQL 端口 → 成功 - 端口填隧道映射的本地端口(如 3307),不是远程 MySQL 的 3306
- 勾选 “Use SSH tunnel”,正确填写 SSH 主机、端口、用户名、认证方式(密钥 or 密码)
真正卡住人的地方,往往不是 SSH 配置本身,而是 MySQL 认证链上某个环节没对齐:host 匹配、plugin 兼容、bind 地址、连接协议选择——四个点只要一个断了,就表现为“SSH 成功,数据库拒绝”。











