根本原因是mysql user表中用户host字段不匹配客户端ip,直接update host风险高;应创建专用远程用户并授权,同时检查bind-address、安全组、防火墙及宝塔权限等外围限制。
navicat 连不上远程 mysql 并报 1130 - host 'xxx.xxx.xxx.xxx' is not allowed to connect to this mysql server,根本原因不是密码错、端口不通或防火墙拦着,而是 mysql 服务端的 user 表里,当前登录用户(比如 root)的 host 字段值不匹配你的客户端 ip —— 它当前是 'localhost',而 navicat 是从另一台机器发起连接的。
直接改 mysql.user 表的 host 字段风险高吗
高。MySQL 官方明确不建议直接 UPDATE user SET host = '%' WHERE user = 'root',因为:
-
mysql.user是系统表,手动更新可能破坏权限结构,尤其在 MySQL 8.0+ 中字段逻辑更复杂(比如新增了password_history、account_locked等) - 如果没执行
FLUSH PRIVILEGES,修改不会生效;但即使刷了,也可能因缓存或复制延迟导致权限不一致 - 把
root@localhost改成root@'%'等于开放 root 账户给任意 IP,一旦密码弱或被爆破,等于交出整库控制权
用 GRANT 创建专用远程用户更安全
应该为 Navicat 单独建一个最小权限账号,而不是动 root。操作步骤如下:
mysql -u root -p USE mysql; CREATE USER 'navi_user'@'%' IDENTIFIED BY 'StrongPass123!'; GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'navi_user'@'%'; FLUSH PRIVILEGES;
说明:
-
'navi_user'@'%'中的%允许任意 IP 连接;如只允许公司内网,写成'navi_user'@'192.168.1.%' - 不要给
ALL PRIVILEGES,除非真要管理全部数据库;生产环境应按需授权到具体库甚至表 - MySQL 8.0+ 默认加密方式是
caching_sha2_password,Navicat 12+ 支持,旧版可能需加参数指定:在连接配置里勾选「使用旧版认证协议」或执行ALTER USER 'navi_user'@'%' IDENTIFIED WITH mysql_native_password BY 'StrongPass123!';
为什么改完 host 还连不上
常见遗漏点:
- 没检查 MySQL 是否监听
0.0.0.0:3306:运行netstat -tlnp | grep :3306,若只显示127.0.0.1:3306,需修改my.cnf中的bind-address = 0.0.0.0并重启服务 - 云服务器(如腾讯云、阿里云)有独立「安全组」规则,必须放行 TCP 3306 端口,且源 IP 范围要包含你的本地公网 IP(或设为
0.0.0.0/0仅测试用) - Linux 本机防火墙(
ufw或firewalld)未开放 3306:例如sudo ufw allow 3306 - Navicat 连接时填的是域名而非 IP,而 MySQL 的
Host匹配基于反向 DNS 解析结果,不稳定;建议统一用 IP 地址连接
宝塔面板用户别跳过「数据库权限」页
如果你用宝塔装的 MySQL,Web 界面里「数据库 → 权限」那一栏不是摆设。即使 SQL 层面已授权,宝塔会额外拦截非白名单 IP 的连接请求。操作路径:
- 进入宝塔面板 → 数据库 → 找到对应数据库 → 点「权限」
- 把「访问权限」从「本地连接」改成「所有人可连接」,或填入你本地的公网 IP(推荐)
- 该操作本质是调用
GRANT并刷新权限,但绕过了手动 SQL 的误操作风险
真正容易被忽略的,是「安全组」和「宝塔权限」这两层外部控制 —— 它们比 MySQL 自身的 user 表权限更早拦截连接请求,查问题时得一层层往外翻,不能只盯着 mysql.user 表看。











