尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Navicat连接阿里云MySQL:安全组、账号授权与SSH通道排错

Navicat连接阿里云MySQL:安全组、账号授权与SSH通道排错 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完整的路径是这样的Navicat 客户端发起 TCP 连接目标是服务器公网IP:3306数据包离开你的本地网络走公网到达阿里云的机房入口阿里云安全组检查这条入方向流量是否符合放行规则不符合直接丢弃流量到达 ECS 实例被操作系统防火墙firewalld、ufw 或 iptables再检查一次到达 MySQL 进程MySQL 检查bind-address配置确定自己是否在这个网卡地址上监听连接建立后MySQL 根据用户名和来源 IP 去mysql.user表里匹配账号匹配不上就返回 1045 或 1130如果密码的认证插件不匹配客户端能力还会在握手阶段报 2059。七步里第 3、4、6、7 步是新手的重灾区。记住这个顺序后面排查的时候按顺序往下卡效率会高很多。1.2 动手前必须确认的三件事在敲任何命令之前我建议你先花两分钟确认下面三件事能省掉后面一半的弯路。第一确认服务器是 ECS 自建 MySQL还是阿里云 RDS。这两者的配置方式完全不同。自建 MySQL 你要自己管安全组、防火墙、账号授权RDS 则由控制台统一管理加白名单就够了服务器上根本没有 SSH 可以登。很多人拿着 RDS 的地址去服务器上找my.cnf找半天找不到就是这个原因。第二确认服务器的公网 IP 和 SSH 端口。阿里云 ECS 控制台的实例列表里能看到公网 IPSSH 默认 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.cnfUbuntu / 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 ufwfirewalld 放行 3306firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload firewall-cmd --list-portsufw 的做法更细一点可以只允许特定来源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_user123.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_userlocalhost所有数据库流量都被 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_userlocalhost IDENTIFIED BY A-Str0ng-Passw0rd!; GRANT ALL PRIVILEGES ON mydb.* TO app_userlocalhost; FLUSH PRIVILEGES;注意如果你的账号建的是app_user%通过 SSH 通道连接时来源 IP 显示为 127.0.0.1也能匹配上%所以两种写法都可以。但用localhost更明确地表达了“只允许本机”的意图。4.3 SSH 通道的一个常见误解有人会问既然通道都建好了为什么还要输 MySQL 的账号密码不能直接免密进去这两个是独立的认证层。SSH 层验证的是“你有没有权限登录这台服务器”MySQL 层验证的是“你有没有权限访问这个数据库”。通道只是把网络打通并不代你完成数据库认证。这个设计其实是合理的——服务器上可能同时跑着好几个库、好几个账号SSH 登录只是入场券。5. 报错速查与逐层排查方法现在讲最实用的部分。下面这张表是我这些年攒下来的按报错编号对照着看。5.1 常见报错对照表报错信息根本原因解决方向2003 - Cant connect to MySQL server (10060)网络层不通检查安全组、防火墙、bind-address2003 - Cant connect to MySQL server (10061)目标端口没有服务在听确认 MySQL 是否启动、端口是否正确1045 - Access denied for user账号或密码不对核对用户名密码检查账号是否存在1130 - Host is not allowed to connect账号的 host 限制授权的 host 不包含你的来源 IP2059 - Authentication plugin cannot be loaded认证插件不兼容升级 Navicat 或改用 mysql_native_password1698 - Access denied for user rootlocalhostroot 走 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;这里能看到每个账号允许的来源主机和认证插件。很多时候问题一眼就出来了——比如只有rootlocalhost没有你要用的账号或者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 -ppassword --single-transaction mydb /data/backup/mydb_$(date \%F).sql--single-transaction这个参数对 InnoDB 表很重要它能在不锁表的情况下拿到一致性快照避免备份期间业务被阻塞。备份文件记得定期清理或者配合find命令只保留最近 30 天find /data/backup -name *.sql -mtime 30 -delete6.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那个瞬间你会感谢自己当初加了这个前缀。
返回列表