MySQL 8.0+ 默认禁止 root 远程登录是设计使然,需确认三件事:权限表中是否存在 root@'%' 等远程条目、mysqld 是否监听外网(bind-address=127.0.0.1)、系统及云平台防火墙是否放行3306端口。

MySQL 8.0+ 默认就不允许 root 远程登录——这不是配置漏了,是设计如此。真正要做的不是“关开关”,而是确认三件事:权限表里有没有残留的 root@'%'、mysqld 是否监听外网、系统和云平台防火墙是否放行了 3306 端口。
查清楚 root@'%' 还在不在 mysql.user 表里
很多人以为删过就没了,结果一查还有:root@'%'、'192.168.%' 或具体公网 IP 都算远程入口。
- 用本地
mysql -u root -p登录后执行:SELECT User, Host FROM mysql.user WHERE User = 'root'; - 如果输出里含
%、0.0.0.0、192.168.x.x或任意非localhost/127.0.0.1的值,说明远程root仍可连 -
localhost和127.0.0.1是两个 host:前者走 Unix socket,后者走 TCP;只留localhost不能防mysql -h 127.0.0.1
用 DROP USER 彻底删掉远程 root,别 UPDATE
UPDATE mysql.user SET host = 'localhost' 在 MySQL 8.0+ 上不可靠:权限缓存可能让旧记录继续生效,FLUSH PRIVILEGES 不保证清空所有上下文,更麻烦的是,一次 CREATE USER 'root'@'%' 就全回来了。
- 执行:
DROP USER 'root'@'%';(不是DELETE FROM mysql.user) - 如有其他网段形式的记录,比如
'root'@'10.0.0.%',也一并DROP USER - 立刻跟一句:
FLUSH PRIVILEGES; - 再查一遍:
SELECT User, Host FROM mysql.user WHERE User = 'root';,结果应只剩'root'@'localhost'或'root'@'127.0.0.1'
bind-address = 127.0.0.1 必须配且重启才生效
删用户只是砍权限,网络层还得关严。哪怕没 root@'%',只要 mysqld 监听 *:3306,攻击者就能用其他高权账号(比如被提权的 dba_admin)连进来。
- 编辑配置文件(常见路径:
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf),在[mysqld]段下写死:bind-address = 127.0.0.1 - 严禁写成
0.0.0.0或注释掉这行——那是默认开放所有接口 - 改完必须重启:
sudo systemctl restart mysql(Debian/Ubuntu)或sudo systemctl restart mysqld(CentOS/RHEL) - 验证是否生效:
sudo ss -tlnp | grep :3306,输出应为127.0.0.1:3306,不是*:3306
防火墙封死 3306 端口的外网访问
云服务器上最容易被忽略的一环:安全组和系统防火墙。MySQL 配置再严,只要 3306 在公网开着,攻击者就能发 SYN 包试探。
- 检查当前状态:
sudo ufw status(Ubuntu)或sudo firewall-cmd --list-ports(CentOS) - 若
3306已开放,立即关闭:sudo ufw deny 3306或sudo firewall-cmd --remove-port=3306/tcp --permanent && sudo firewall-cmd --reload - 如需内网某台应用服务器连接,先放行特定 IP:
sudo ufw allow from 192.168.10.5
最常被忽略的是:删了 root@'%' 后没重启服务,或者 bind-address 改了但没验证监听地址——ss -tlnp 输出才是唯一可信依据。安全不是“做了就行”,是每一步都得实测闭环。


















