远程MySQL连接需三步:创建指定认证插件的专用用户(如mysql_native_password)、修改bind-address=0.0.0.0并重启服务、同步开放防火墙与云安全组3306端口。
很多人以为只要 UPDATE mysql.user SET host='%' WHERE user='root' 就能远程登录,其实这步只是“开了门缝”,但 MySQL 8.0+ 默认用 caching_sha2_password 认证插件,老客户端(如 Navicat 旧版、某些 Python 驱动)根本连不上——会报错 ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded。
正确做法是:先创建专用用户(不碰 root),再指定认证方式:
CREATE USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'StrongPass123!'; GRANT SELECT, INSERT ON myapp.* TO 'app_user'@'%'; FLUSH PRIVILEGES;
mysql_native_password,兼容性拉满myapp.*,不给 *.*(生产环境严禁)UPDATE user 改 root 的 host——MySQL 8.0+ 的 user 表结构更严格,可能触发校验失败MySQL 默认配置是 bind-address = 127.0.0.1,意味着它只监听本地回环地址。哪怕用户权限全开、防火墙也放行,外部请求根本进不来,客户端会卡在 Connecting to MySQL server... 或直接报 ERROR 2003 (HY000): Can't connect to MySQL server。
必须修改配置文件并重启服务:
/etc/mysql/mysql.conf.d/mysqld.cnf
my.ini(MySQL 安装目录下)bind-address 行,改为:bind-address = 0.0.0.0(或指定内网 IP,如 192.168.1.100)sudo systemctl restart mysql(Linux)或服务管理器中重启(Windows)⚠️ 注意:改完不重启 = 白改;改了但没注释掉原有 bind-address 行(配置文件里出现两行)= 以第一行为准,可能仍为 127.0.0.1。
本地测试通 ≠ 外网能连。Linux 防火墙(firewalld / ufw)和云厂商安全组(阿里云/腾讯云/AWS)必须都放行 3306/tcp。
常见漏点:
0.0.0.0/0 却没加描述,后续审计难追溯推荐最小化开放:
# 仅允许公司办公网段访问(示例) sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="3306" protocol="tcp" accept'
MySQL 认证时,不是只看用户名,而是查 user@host 这个完整组合。比如:
'admin'@'localhost' 和 'admin'@'%' 是两个完全独立的账号,密码、权限互不影响'admin'@'192.168.1.50' → 'admin'@'192.168.1.%' → 'admin'@'%',按最精确匹配生效'root'@'%',而应建 'deploy'@'192.168.10.%' 这类带子网限制的账号查当前所有远程可登录账号:
SELECT User, Host FROM mysql.user WHERE Host != 'localhost';
网络环境越复杂,越要靠 Host 字段做第一道隔离——这是比应用层 IP 黑白名单更底层、
更可靠的控制点。