远程 MySQL 连接需三步:创建指定认证插件的专用用户(如 mysql_native_password)、修改 bind-address=0.0.0.0 并重启服务、同步开放防火墙与云安全组 3306 端口。

远程用户必须显式创建,不能只改 host 字段
很多人以为只要 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 表结构更严格,可能触发校验失败
bind-address 不设为 0.0.0.0,远程连接必失败
MySQL 默认配置是 bind-address = 127.0.0.1,意味着它只监听本地回环地址。哪怕用户权限全开、防火墙 也放行,外部请求根本进不来,客户端会卡在 Connecting to MySQL server…… 或直接报 ERROR 2003 (HY000): Can't connect to MySQL server。
必须修改配置文件并重启服务:
- Linux 路径:
/etc/mysql/mysql.conf.d/mysqld.cnf - Windows 路径:
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。
常见漏点:
- 只开了防火墙,忘了在阿里云控制台配安全组入方向规则
- 开了 3306,但协议选了 UDP(MySQL 只走 TCP)
- 安全组规则目标 IP 写成
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'@'%'是两个完全独立的账号,密码、权限互不影响 - 客户端从 192.168.1.50 连接,MySQL 会优先匹配
'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 黑白名单更底层、更可靠的控制点。






























