根本原因是MySQL用户权限中host字段不匹配远程客户端IP,需用CREATE USER/ALTER USER创建'username'@'%'用户并GRANT授权、FLUSH PRIVILEGES,同时将bind-address设为0.0.0.0、开放防火墙及云安全组3306端口。

远程连接 MySQL 报错 Host 'xxx' is not allowed to connect to this MySQL server,根本不是密码或网络不通的问题,而是 MySQL 服务压根没认出你的来源主机——它连校验密码那步都跳过了。
确认当前连接实际匹配的 'user'@'host' 组合
错误信息里写的 'root'@'192.168.1.100' 或 'app'@'win-abc' 就是 MySQL 实际拒绝的账号全名。这个 user 和 host 必须完全匹配,'root'@'localhost' 和 'root'@'127.0.0.1' 是两个独立账号,互不通用。
- 执行
SELECT User, Host FROM mysql.user WHERE User = 'your_username';,看结果里有没有和你连接时一模一样的User和Host - 如果只看到
'myuser'@'localhost',但你是从远程 IP 连的,那这条记录根本不会被选中 - 注意:MySQL 会按
Host字段做最长前缀匹配,'192.168.1.%'不匹配 IPv6 地址,'%.example.com'也不匹配纯 IP
用 CREATE USER 或 ALTER USER 创建/修正远程用户
别直接 UPDATE mysql.user SET host = '%' —— MySQL 8.0+ 会报 ERROR 1396 (HY000),且绕过密码加密逻辑,导致后续登录失败。
- 如果用户还不存在远程版本:
CREATE USER 'myuser'@'%' IDENTIFIED WITH mysql_native_password BY 'mypass';(加WITH mysql_native_password避免老客户端认证失败) - 如果已有但
host不对:ALTER USER 'myuser'@'localhost' RENAME TO 'myuser'@'%'; - 授权必须显式执行:
GRANT SELECT, INSERT ON mydb.* TO 'myuser'@'%';(不要省略@'%') - 最后必须
FLUSH PRIVILEGES;,否则内存缓存不更新,改了也白改
检查 bind-address 和防火墙是否拦在 MySQL 外面
即使权限全开了,bind-address = 127.0.0.1 会让 MySQL 只监听本地回环,远程请求连 TCP 握手都进不来;而防火墙或云平台安全组则可能把包丢在系统层。
- 查监听地址:
netstat -tlnp | grep :3306,如果只显示127.0.0.1:3306,说明配置没生效 - 改配置文件(如
/etc/mysql/mysql.conf.d/mysqld.cnf),把bind-address设为0.0.0.0或注释掉;同时确认没有skip-networking开启 - Linux 防火墙:
sudo ufw allow 3306或sudo firewall-cmd --add-port=3306/tcp --permanent - 云服务器必须额外检查安全组规则——本地
ufw放行了,阿里云/腾讯云控制台里没开 3306 入方向,照样连不上
真正容易卡住的地方,是 host 匹配的精确性、FLUSH PRIVILEGES 的遗漏、以及云环境里安全组和本地防火墙的双重拦截——三者任缺其一,都会让错误看起来像“权限问题”,实际连 MySQL 的门都没摸到。


















