根本原因是root用户长期暴露在攻击面下,必须禁用远程root登录、启用connection_control插件(需同时安装两个组件)、强制密码复杂度、绑定监听地址并配置防火墙封堵3306端口。

MySQL root 用户被暴力破解,根本原因不是“密码不够强”,而是它长期暴露在攻击面下——允许远程登录、未限制来源、无失败拦截、权限未收敛。单独改个密码解决不了问题,必须切断攻击路径。
禁用所有远程 root 登录,只留 'root'@'localhost'
这是最直接有效的一步。只要 'root'@'%' 或 'root'@'192.168.%' 这类账号存在,暴力破解就始终可行。
- 先查清楚当前有哪些 root 实例:
SELECT user, host FROM mysql.user WHERE user = 'root'; - 删掉所有非
localhost的 root:DROP USER 'root'@'%';(注意:不是DELETE FROM mysql.user) - 确认只剩
'root'@'localhost'后,再重置其密码(避免空密码残留):ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourStrongPass2026!'; - 立刻执行
FLUSH PRIVILEGES;,否则新密码不生效
启用 connection_control 插件,但必须装齐两个组件
这个插件常被误以为“开了就防爆破”,实际它默认对 'root'@'localhost' 完全绕过,且少装一个组件就等于没装。
- 必须同时安装两个插件:
INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';和INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so'; - 检查是否都激活:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME IN ('CONNECTION_CONTROL', 'CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS');两行都得是ACTIVE - 参数必须写进
my.cnf才持久化,SET GLOBAL重启即失效:connection_control_failed_connections_threshold = 5<br>connection_control_min_connection_delay = 1000<br>connection_control_max_connection_delay = 5000
- 注意:
connection_control_min_connection_delay单位是毫秒,不是秒;max值别设太高(如超过 10 秒),否则可能拖垮连接池
用 validate_password 强制 root 密码复杂度
MySQL 8.0+ 默认加载了 validate_password,但策略默认是 LOW,等同于没开。
- 检查当前策略:
SHOW VARIABLES LIKE 'validate_password%';,重点关注validate_password.policy - 设为
MEDIUM或更高:SET GLOBAL validate_password.policy = MEDIUM;(要求大小写字母 + 数字 + 特殊字符,最小长度 8) - 密码必须满足策略,否则
ALTER USER会报错:ERROR 1819 (HY000): Your password does not satisfy the current policy requirements - 该设置同样需写入
my.cnf的[mysqld]段落,否则重启后回退
绑定监听地址 + 防火墙双重封堵 3306 端口
插件和密码策略都是“守门人”,而 bind-address 和防火墙才是“把门焊死”。
- 在
my.cnf中强制只监听本地:bind-address = 127.0.0.1(如果应用也在本机)或内网 IP(如192.168.1.100),绝不能留0.0.0.0 - 即使 MySQL 绑定了内网地址,也要在系统层封住 3306 入向流量:
iptables -A INPUT -p tcp --dport 3306 ! -s 192.168.1.0/24 -j DROP(仅允许可信内网段) - 云服务器务必检查安全组规则,禁止 3306 对公网开放——哪怕只开 1 分钟,扫描器就能扫到
- 验证是否生效:
netstat -tlnp | grep :3306应只显示127.0.0.1:3306或指定内网地址,而非*:3306
真正难的不是某一条命令怎么写,而是每一步都得闭环:插件装了但没配阈值,等于白装;密码改了但 root 还能从公网连,等于裸奔;防火墙开了但 bind-address 是 0.0.0.0,等于门开着锁着窗。安全不是加功能,是做减法——删掉所有非必需的账号、权限、监听地址和协议支持。











