☰
Navicat连接阿里云MySQL:安全组、账号授权与SSH通道排错
2026/9/30 5:30:54 网站建设 项目流程

1. 连不上数据库这件事,九成问题其实不在 Navicat

上周又有个学弟来找我,说他在阿里云服务器上装好了 MySQL,本地装了 Navicat,结果怎么点“测试连接”都是红的,报错换来换去,一会儿 2003,一会儿 1045,折腾了整整两天。我远程看了一下,五分钟就解决了——问题根本不在 Navicat,而是安全组没放行,加上账号只允许 localhost 登录。

这类场景我见过太多次了。Navicat 连接阿里云服务器上的 MySQL 数据库,听上去是一条很短的链路,实际上中间要穿过五道门:本地客户端、公网传输、阿里云安全组、服务器本机防火墙、MySQL 自身的监听地址与账号授权。任何一道门没开,你在 Navicat 界面上看到的都是同一个结果——连不上,但报错信息完全不一样,这就是新手最容易懵的地方。

这篇内容我打算把整条链路拆开讲透。从阿里云侧的安全组配置、服务器上的 MySQL 参数调整,到 Navicat 端的连接参数怎么填、SSH 通道怎么用,再到七八种典型报错的定位方法,全部给出可以直接照抄的命令和参数。不管你是做数据库课程设计的学生党,还是刚接手一台云服务器准备部署业务的后端同学,或者只是想用 Navicat 这种图形化工具管理远程数据库的运维新手,都能照着走一遍。

我先说一个结论性的判断:如果你连的是阿里云自建 MySQL,最省心的方案不是直接开放 3306 端口,而是走 SSH 通道。这个后面会详细讲。至于为什么不建议用 root 账号远程登录、为什么 MySQL 8.0 会冒出一个 2059 的怪错误、字符集和时区为什么必须手动指定,这些坑我都会一个一个填上。

1.1 先把整条链路画清楚

很多人排查问题的方式是“瞎试”——关防火墙、改端口、重装 MySQL,能试的都试一遍。这种方式偶尔能碰对,但下一次换个环境还是不会。

正确的做法是先知道数据包要经过哪些节点。从你本地的 Navicat 到阿里云上的 MySQL,完整的路径是这样的:

  1. Navicat 客户端发起 TCP 连接,目标是<服务器公网IP>:3306;
  2. 数据包离开你的本地网络,走公网到达阿里云的机房入口;
  3. 阿里云安全组检查这条入方向流量是否符合放行规则,不符合直接丢弃;
  4. 流量到达 ECS 实例,被操作系统防火墙(firewalld、ufw 或 iptables)再检查一次;
  5. 到达 MySQL 进程,MySQL 检查bind-address配置,确定自己是否在这个网卡地址上监听;
  6. 连接建立后,MySQL 根据用户名和来源 IP 去mysql.user表里匹配账号,匹配不上就返回 1045 或 1130;
  7. 如果密码的认证插件不匹配客户端能力,还会在握手阶段报 2059。

七步里,第 3、4、6、7 步是新手的重灾区。记住这个顺序,后面排查的时候按顺序往下卡,效率会高很多。

1.2 动手前必须确认的三件事

在敲任何命令之前,我建议你先花两分钟确认下面三件事,能省掉后面一半的弯路。

第一,确认服务器是 ECS 自建 MySQL,还是阿里云 RDS。这两者的配置方式完全不同。自建 MySQL 你要自己管安全组、防火墙、账号授权;RDS 则由控制台统一管理,加白名单就够了,服务器上根本没有 SSH 可以登。很多人拿着 RDS 的地址去服务器上找my.cnf,找半天找不到,就是这个原因。

第二,确认服务器的公网 IP 和 SSH 端口。阿里云 ECS 控制台的实例列表里能看到公网 IP,SSH 默认 22 端口,如果你改过就要用自己的。这个信息后面 Navicat 的 SSH 通道要用到。

第三,确认本地网络出口的公网 IP。这个 IP 是用来配安全组白名单的。直接搜索引擎搜“IP”就能看到,或者在服务器上执行who am i、echo $SSH_CLIENT也能看到你连过去的来源地址。注意家庭宽带一般是动态 IP,过几天可能会变,这点后面会讲怎么处理。

2. 阿里云服务端的配置,一步都不能少

服务端要改的东西其实就三块:MySQL 的监听配置、云平台的安全组、操作系统防火墙。三块都通了,Navicat 才有可能连上。我按顺序讲。

2.1 让 MySQL 真正监听外部地址

MySQL 默认的bind-address在不少发行版上是127.0.0.1,意思是只接受本机连接。这种情况下,哪怕你安全组开得再大,外面也进不来。

先确认当前监听状态:

ss -lntp | grep 3306

如果输出是127.0.0.1:3306,说明只监听本地;如果看到0.0.0.0:3306或:::3306,说明已经在监听所有地址了。

改配置的位置因发行版而异,常见的几个路径:

发行版 / 安装方式配置文件路径
CentOS / RHEL 系/etc/my.cnf
Ubuntu / Debian apt 安装/etc/mysql/mysql.conf.d/mysqld.cnf
宝塔面板安装/etc/my.cnf
编译安装通常在 /etc/my.cnf 或编译时指定的路径

找到[mysqld]段,加上或修改这一行:

[mysqld] bind-address = 0.0.0.0

改完重启:

systemctl restart mysqld # CentOS 系 systemctl restart mysql # Ubuntu / Debian 系

提示:bind-address = 0.0.0.0的含义是“在所有网卡上监听”,并不等于“谁都能登进来”。真正的准入控制靠的是安全组和账号授权,这两层配好了,监听地址放开是安全的。不过如果你的方案是走 SSH 通道,这一项其实可以不动,保持 127.0.0.1 反而更干净。

这里有个容易被忽略的细节:某些发行版的 MySQL 还会额外读取/etc/mysql/conf.d/下的配置文件,如果有多个文件同时出现bind-address,后加载的会覆盖前面的。改完记得systemctl status看一眼启动日志,确认没有语法报错。

2.2 阿里云安全组:只放行你需要的来源

安全组是阿里云层面的虚拟防火墙,比操作系统防火墙更靠前。它的规则是白名单机制——没显式放行的,一律拒绝。

操作路径是:ECS 控制台 → 实例 → 找到你的实例 → 安全组 → 配置规则 → 入方向 → 手动添加。

要加的规则大致是这样:

字段填写内容
授权策略允许
优先级1(数字越小优先级越高)
协议类型自定义 TCP
端口范围3306/3306
授权对象你的公网 IP + /32,例如 123.45.67.89/32
描述Navicat 远程连接 MySQL

授权对象这里我想多说两句。很多人图省事直接填0.0.0.0/0,意思是允许全世界访问 3306 端口。这个做法在测试环境偶尔能接受,但放到有任何真实数据的服务器上就是灾难——公网上有大量自动化脚本在全网扫 3306 端口,扫到之后就是暴力破解密码,运气差一点的服务器几天之内就会被人挂上东西。

所以我的习惯是:授权对象永远写自己的 IP 加 /32。如果家里宽带是动态 IP,几天变一次,那有两个选择:一是每次变了之后去控制台改一下,二是干脆改用 SSH 通道方案,只放行 22 端口(而且 22 端口也建议限制来源)。

2.3 别忘了服务器上的本机防火墙

安全组放行了,服务器上的防火墙还可能拦着。先看用的是哪个:

# CentOS 7 以上 systemctl status firewalld # Ubuntu systemctl status ufw

firewalld 放行 3306:

firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload firewall-cmd --list-ports

ufw 的做法更细一点,可以只允许特定来源:

ufw allow from 123.45.67.89 to any port 3306 proto tcp ufw status

如果你走的是 SSH 通道方案,那这里就不需要动 3306,因为它只在本机访问。

2.4 创建专用账号,别用 root 远程登录

这一步是最容易出事的地方。很多人为了省事,直接用 root 账号连,还把它改成root@'%'。我要认真说一句:不要这么干。

原因很直接。root 拥有DROP DATABASE、FILE、GRANT这类高危权限,一旦密码泄露(比如被人拿到 Navicat 里保存的连接配置,或者密码在代码里硬编码),攻击者可以直接拖库、删库、写文件。而且 MySQL 的 root 账号在很多云服务器上是被各种工具默认尝试的用户名,暴露在公网上就是活靶子。

正确的做法是建一个权限刚好够用的专用账号:

CREATE USER 'app_user'@'%' IDENTIFIED BY 'A-Str0ng-Passw0rd!'; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'%'; FLUSH PRIVILEGES;

如果你只是做课程设计、要用 Navicat 建表改表,那就给 DDL 权限:

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP, REFERENCES ON mydb.* TO 'app_user'@'%';

'app_user'@'%'里的%代表任意来源主机。如果你想更严格一点,可以写成'app_user'@'123.45.67.89',这样只有这个 IP 能连。缺点是动态 IP 一变就得重新授权,看你自己的取舍。

还有一点值得提醒:MySQL 8.0 默认的认证插件是caching_sha2_password,而部分旧版 Navicat 客户端不认识这个插件,握手阶段就会报 2059。如果你不想升级 Navicat,可以在建账号的时候显式指定旧插件:

CREATE USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'A-Str0ng-Passw0rd!';

或者对已有账号改:

ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'A-Str0ng-Passw0rd!'; FLUSH PRIVILEGES;

我更推荐的顺序是:先试着用现在的 Navicat 版本连,报 2059 再考虑改插件;能升级客户端就升级客户端。原因在于mysql_native_password在新版本 MySQL 里已经是被标记为废弃的插件,长期看迟早要迁移,能一次到位就一次到位。

3. Navicat 端的参数怎么填才不出错

服务端配好了,客户端其实就几个空格。但就是这几个空格,填错一个就连不上。

3.1 版本选择与安装来源

先聊一个绕不开的问题:用哪个 Navicat。

Navicat 是商业软件,官方提供 14 天全功能试用。如果你只是想临时用一下,试用期完全够跑完一个课程设计。如果你需要长期用,官方有Navicat Premium Lite这个免费版本,功能相比付费版有缩减(比如不带数据传输、结构同步等高级功能),但对日常的增删改查、建表、写 SQL 来说够用了。付费版就是 Navicat Premium,支持 MySQL、PostgreSQL、SQLite、Oracle 等多种数据库。

我想强调的是安装来源。网上流传的各种“绿色版”“注册机版”安装包,我强烈建议不要碰。原因不是道德说教,而是真实的账号泄露风险。这类二次打包的安装包被植入信息收集程序的比例相当高,而你用它去连的往往是有真实业务数据的数据库,等于把钥匙连同地址一起交出去。我在帮人处理过的几次数据异常事件里,追到最后都指向了来路不明的数据库客户端。

从官网下载,试用、用 Lite 版、或者买授权,都比冒这个风险划算。

3.2 新建连接的核心参数

打开 Navicat,点“连接” → “MySQL”,弹出的表单里几个关键字段:

字段填写内容说明
连接名随便起,比如 prod-mysql只影响本地显示
主机服务器公网 IP走 SSH 通道时这里填 127.0.0.1
端口3306改过 MySQL 端口的话按实际填
用户名app_user就是上面建的那个专用账号
密码对应的密码建议勾选保存密码
字符集utf8mb4不填容易出中文乱码
时区Asia/Shanghai 或 +08:00影响时间字段显示

字符集这一项,我踩过的坑是这样的:默认情况下 Navicat 可能按 Latin1 处理,结果中文存进去再读出来就是问号。utf8mb4是utf8的超集,支持完整的四字节字符(包括一些特殊符号),现在建库建表基本都用它,客户端也保持一致最省事。

时区这一项更隐蔽。MySQL 的时间字段存的是DATETIME和TIMESTAMP两种。TIMESTAMP会受会话时区影响,如果服务端时区是 UTC、客户端按本地时区解读,你看到的创建时间就会差 8 小时。填上+08:00能避开大部分混乱。

3.3 高级设置里值得改的几项

点“高级”标签页,下面这几项我一般会动:

  • 保持连接间隔:默认可能是 240 秒。如果你经常挂着 Navicat 不动,回来发现连接断了,把它调小一点,比如 60 秒,客户端会定期发心跳包保持会话。
  • 使用压缩:跨地域连接(比如服务器在华北、你在华南)时勾上,能减少传输量,但会增加一点 CPU 开销,本地网络就没必要。
  • 自动重连:建议勾上,网络抖动的时候能自动恢复。

配置完成后点左下角的“测试连接”。这里有个小技巧:别急着点“确定”保存。先把“测试连接”点通,确认无误再保存,否则一个错误的连接配置会被记住,下次打开还得改。

4. 更省心的方案:用 SSH 通道连接

前面提过,我更推荐走 SSH 通道。这一节把原理和参数讲清楚。

4.1 为什么推荐这种方式

直接开放 3306 到公网,本质上是把数据库监听的端口暴露在互联网上。哪怕你限制了来源 IP、设了强密码,风险依然存在:密码可能被日志记录、可能被中间人截获(尤其是早年用明文协议的场景)、可能因为某个配置疏忽而短暂暴露。

SSH 通道的思路完全不同。它的做法是:Navicat 先通过 SSH 协议登录到服务器(用你平时 SSH 登录的那套凭据),然后在服务器本机内部访问 127.0.0.1:3306。整个过程中,MySQL 只接受来自本机的连接,公网上根本不开放 3306 端口。

这样带来几个实际的好处:

  • 安全组里完全不需要放行 3306,只留 22 端口即可,攻击面大幅缩小;
  • MySQL 的bind-address可以保持127.0.0.1不动,连账号都可以只授权'app_user'@'localhost';
  • 所有数据库流量都被 SSH 加密通道包住,公网上看不到明文;
  • 家里是动态 IP 也不影响,因为连接的身份验证靠的是 SSH 密钥或密码,不依赖来源 IP。

代价是多了一次 SSH 登录的开销,理论上延迟会略高一点点,但日常使用完全感知不到。我自己的所有云服务器数据库连接都走这条路,几年下来没出过问题。

4.2 参数具体怎么填

在 Navicat 的连接配置里切到SSH标签页,勾选“使用 SSH 隧道”,然后:

字段填写内容
主机服务器公网 IP(和 SSH 登录的地址一样)
端口22(改过 SSH 端口就填实际的)
用户名你的 Linux 登录用户,比如 root 或 ubuntu
认证方式密码 或 公钥
密码 / 私钥文件对应的凭据

如果你用的是密钥登录(现在阿里云新建实例默认推荐这种方式),认证方式选“公钥”,然后选择本地保存的.pem或id_rsa私钥文件。注意这个私钥的权限,在 Windows 上一般无所谓,在 macOS / Linux 上必须是 600,否则 SSH 会拒绝使用。

关键的一步在“常规”标签页:走 SSH 通道之后,那里的“主机”要填127.0.0.1或localhost,端口填3306。很多人这里忘了改,还填着公网 IP,结果通道建好了但数据库连不上,报的还是 2003,白折腾半天。

因为这个127.0.0.1是从服务器视角看的,所以 MySQL 的bind-address保持默认的127.0.0.1就完全没问题。同理,账号可以建得保守一点:

CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'A-Str0ng-Passw0rd!'; GRANT ALL PRIVILEGES ON mydb.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES;

注意:如果你的账号建的是'app_user'@'%',通过 SSH 通道连接时来源 IP 显示为 127.0.0.1,也能匹配上%,所以两种写法都可以。但用localhost更明确地表达了“只允许本机”的意图。

4.3 SSH 通道的一个常见误解

有人会问:既然通道都建好了,为什么还要输 MySQL 的账号密码,不能直接免密进去?

这两个是独立的认证层。SSH 层验证的是“你有没有权限登录这台服务器”,MySQL 层验证的是“你有没有权限访问这个数据库”。通道只是把网络打通,并不代你完成数据库认证。这个设计其实是合理的——服务器上可能同时跑着好几个库、好几个账号,SSH 登录只是入场券。

5. 报错速查与逐层排查方法

现在讲最实用的部分。下面这张表是我这些年攒下来的,按报错编号对照着看。

5.1 常见报错对照表

报错信息根本原因解决方向
2003 - Can't connect to MySQL server (10060)网络层不通检查安全组、防火墙、bind-address
2003 - Can't connect to MySQL server (10061)目标端口没有服务在听确认 MySQL 是否启动、端口是否正确
1045 - Access denied for user账号或密码不对核对用户名密码,检查账号是否存在
1130 - Host is not allowed to connect账号的 host 限制授权的 host 不包含你的来源 IP
2059 - Authentication plugin cannot be loaded认证插件不兼容升级 Navicat 或改用 mysql_native_password
1698 - Access denied for user 'root'@'localhost'root 走 socket 认证改认证方式或新建账号
2005 - Unknown MySQL server host主机名解析失败检查主机名拼写、DNS 设置
1049 - Unknown database库名写错或不存在确认数据库已创建
连接超时无报错网络被静默丢弃通常是安全组规则没生效

5.2 我的逐层排查流程

遇到连不上,我一般是这么走的,从外往里一层层剥:

第一步,用 telnet 或 nc 测通不通。

telnet 123.45.67.89 3306 # 或者 nc -zv 123.45.67.89 3306

如果这一步不通,问题一定在安全组或防火墙,不用往 MySQL 那边想。这一步能省掉大量无效排查。

第二步,在服务器本机测试 MySQL 是否正常。

mysql -u app_user -p -h 127.0.0.1

本机能连、外面不能连,说明 MySQL 本身没问题,是网络准入的问题。本机也连不上,那就是账号或 MySQL 服务的问题。

第三步,看 MySQL 的账号表。

SELECT user, host, plugin FROM mysql.user;

这里能看到每个账号允许的来源主机和认证插件。很多时候问题一眼就出来了——比如只有root@localhost,没有你要用的账号,或者host字段是localhost而不是%。

第四步,看错误日志。

tail -n 100 /var/log/mysql/error.log # Ubuntu tail -n 100 /var/log/mysqld.log # CentOS

连接被拒绝的详细原因,MySQL 都会记在这里,比客户端看到的报错信息详细得多。

5.3 几个特别隐蔽的坑

坑一:改了安全组但不生效。阿里云安全组规则修改后通常几秒内生效,但偶尔会有短暂延迟。如果确认规则没问题还是连不上,等一分钟再试,或者把规则删掉重新加一遍。

坑二:多个安全组叠加。一台 ECS 可以加入多个安全组,规则是并集——只要有一个安全组放行了就通。但反过来,如果某个安全组里有一条拒绝规则,可能会覆盖掉另一个安全组的允许规则。排查的时候记得把实例关联的所有安全组都看一遍。

坑三:MySQL 8.0 的密码策略。8.0 引入了validate_password组件,如果启用了,你设的简单密码会被直接拒绝,报的是密码不符合策略而不是权限问题。真要设简单密码做测试,先看策略:

SHOW VARIABLES LIKE 'validate_password%';

坑四:宝塔面板的干扰。如果服务器装了宝塔,它可能自己管着一套防火墙规则,跟系统 firewalld 并存。宝塔的“安全”页面里也有端口放行设置,两处都要检查。

坑五:本地公司网络限制。有些办公网络会限制对外网非标准端口的访问,这种情况下 3306 会被本地出口拦掉。换手机热点试一下就能确认。

6. 一些长期维护的实操心得

连接问题解决之后,日常使用还有几个习惯,能帮你少走很多弯路。

6.1 账号和权限的最小化

我给每个应用单独建账号,权限只开到它需要的表和操作。比如一个只读的报表服务,就只给SELECT;一个只写日志的服务,就只给INSERT。听起来麻烦,但真出问题的时候,这个习惯能救命——某个服务的配置泄露了,损失被限制在它自己的权限范围内。

Navicat 这种客户端连生产库,我一般会用一个权限中等的账号,够建表改表就行,不做DROP DATABASE这种操作。真要删库,我会单独用一个高权限账号,用完就断开。

6.2 用 Navicat 自带的同步能力

Navicat 有个容易被忽略的能力:数据传输和数据同步。前者是把一个库的结构加数据整体搬到另一个库,后者是只同步差异数据。做本地开发库和服务器测试库之间的同步,这两个功能比手动导 SQL 文件高效得多。

用的方法是:右键源数据库 → “数据传输” → 选择目标连接和数据库 → 勾选要传的表 → 开始。注意第一次用之前先在测试环境跑一遍,因为“数据传输”默认可能会先删目标表再重建,跑错方向就是灾难。把“遇到错误继续”这类选项看仔细。

6.3 备份这件事,别等出事才想起来

连上数据库之后第一件事,我建议是配好备份。Navicat 里可以设置自动运行的备份任务,定时把库导出成 SQL 文件。但我不太建议只依赖客户端备份,原因是客户端得开着电脑才跑。

更可靠的做法是在服务器上用mysqldump加 crontab:

# 每天凌晨 3 点备份 0 3 * * * /usr/bin/mysqldump -u backup_user -p'password' --single-transaction mydb > /data/backup/mydb_$(date +\%F).sql

--single-transaction这个参数对 InnoDB 表很重要,它能在不锁表的情况下拿到一致性快照,避免备份期间业务被阻塞。备份文件记得定期清理,或者配合find命令只保留最近 30 天:

find /data/backup -name "*.sql" -mtime +30 -delete

6.4 版本升级时留意协议变化

MySQL 从 5.7 升到 8.0,除了前面说的认证插件变化,还有几个容易踩的点。一是GROUP BY的严格模式默认开启了,之前那些写法不规范的 SQL 会直接报错;二是保留字增加了不少(比如RANK、GROUPS),之前能用作用户名或列名的字段可能需要加反引号;三是默认字符集从latin1变成了utf8mb4,这个变化是好事,但升级时要注意旧数据的兼容。

Navicat 这边,Premium 17 对 MySQL 8.0 及更高版本的支持比较完整,包括新的认证插件和窗口函数。如果你用的还是比较老的版本,升级到 16 以上会省很多事。

最后分享一个我自己的小习惯:每配好一个数据库连接,我会在连接名后面加一个标记,比如prod-mysql、test-mysql、local-mysql。看起来很傻,但生产库和测试库摆在同一个连接列表里,界面又长得几乎一样,手一抖点错目标执行了一条DELETE而没加WHERE,那个瞬间你会感谢自己当初加了这个前缀。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询