必须将bind-address设为0.0.0.0或具体内网ip,不能保留默认127.0.0.1;需同步创建带正确host的用户、授权、刷新权限,并开放防火墙及云安全组3306端口。

bind-address 必须设为 0.0.0.0 或具体内网 IP,不能留默认值
MySQL 默认 bind-address = 127.0.0.1,哪怕用户权限全开,也只会收本机连接。远程连不上,八成卡在这一步。
修改配置文件(常见路径:/etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf)的 [mysqld] 段:
- 若需允许某内网段(如
192.168.1.0/24)访问,且 MySQL 服务器本身有固定内网 IP(比如192.168.1.10),设为bind-address = 192.168.1.10更稳妥 - 若必须监听所有接口(例如云服务器需响应公网请求),设为
bind-address = 0.0.0.0 - 务必确认配置中没有
skip-networking这行——有就注释掉或删掉 - 改完执行
sudo systemctl restart mysql(Ubuntu/Debian)或sudo systemctl restart mysqld(CentOS/RHEL)
CREATE USER 和 GRANT 必须带精确 host,且引号不可省略
MySQL 的权限是 'user'@'host' 组合识别的,'app_user'@'localhost' 和 'app_user'@'192.168.1.50' 是两个完全独立的账户,密码可不同。
要允许 192.168.1.0/24 网段访问,用通配符 %,但写法必须严格:
-
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'StrongPass2026!';✅ 正确:点号后接%,引号包裹 -
CREATE USER 'app_user'@'192.168.1.*' ...❌ 错误:*不是 MySQL 通配符,会创建一个字面量为192.168.1.*的 host -
GRANT SELECT, UPDATE ON mydb.users TO 'app_user'@'192.168.1.%';—— 权限范围按需收紧,别直接GRANT ALL - 执行完必须
FLUSH PRIVILEGES;,否则新权限不生效(这步跳过是高频失误)
防火墙和云平台安全组必须同步放行 3306 TCP 入向
即使 MySQL 已监听 0.0.0.0:3306 且用户权限正确,系统级防火墙或云厂商安全组仍可能拦截连接请求。
检查与配置要点:
- 本地防火墙:Ubuntu 上用
sudo ufw allow from 192.168.1.0/24 to any port 3306 proto tcp;CentOS 上用sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' --permanent - 云服务器(阿里云、腾讯云等):必须在控制台的安全组规则里添加入方向规则,源 IP 填
192.168.1.0/24,协议端口填TCP:3306 - 验证监听状态:登录服务器后运行
netstat -tlnp | grep :3306,应看到0.0.0.0:3306或192.168.1.10:3306,而非仅127.0.0.1:3306
ERROR 1130 “Host … is not allowed to connect” 的真实原因只有两个
这个错误不是网络不通,而是 MySQL 明确拒绝了认证——只可能是以下其一:
- MySQL 中不存在
'app_user'@'192.168.1.50'这条记录(注意:哪怕有'app_user'@'%',也不等于覆盖'app_user'@'192.168.1.50') - 存在该记录,但密码校验失败(比如你用的是 MySQL 8.0+,而客户端仍用旧版驱动,默认使用
caching_sha2_password插件;此时需显式指定ALTER USER 'app_user'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY '...';)
排查时先运行 SELECT user, host FROM mysql.user WHERE user = 'app_user';,确认输出里真有对应 host 的行;再检查客户端连接时用的 host 是否和授权时完全一致(大小写、空格、IP 格式)。
真正容易被忽略的是:MySQL 会优先匹配最具体的 host(比如 '192.168.1.50' 优先于 '192.168.1.%'),如果同时存在多个同名用户但 host 不同,权限行为可能出乎意料。











