connection_control插件默认绕过localhost连接,因此无法防护root@localhost的暴力破解;需配合专用管理账号、失败登录计数表及账户锁定策略,并将配置写入my.cnf持久化。

不能只靠 connection_control 插件防住对 root 密码的暴力破解——它默认绕过 localhost 连接,而 root 通常正是通过 'root'@'localhost' 登录的。真要防护,得先改用远程可管账号 + 插件 + 账户锁定三者配合。
为什么 root@localhost 永远不会被 connection_control 延迟?
插件硬编码白名单:localhost、127.0.0.1、::1 以及所有 skip-grant-tables 模式下的连接,全部跳过失败计数和延迟逻辑。这不是 bug,是设计——避免管理员自己把自己锁在外面。
实操建议:
- 查当前登录身份:
SELECT USER(), CURRENT_USER();,如果返回'root'@'localhost',那无论输错多少次,connection_control_failed_connections_threshold都不生效 - 生产环境必须创建专用管理账号,例如:
CREATE USER 'dba'@'192.168.10.50' IDENTIFIED BY 'strongpwd' WITH MAX_CONNECTIONS_PER_HOUR 10; -
root账号应仅保留'root'@'127.0.0.1'或'root'@'::1',并禁用'root'@'%'和'root'@'localhost'(后者会覆盖前者)
connection_control 插件必须装两个组件才起作用
只执行 INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so'; 是不够的。失败计数依赖配套表 CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS,没它,SHOW VARIABLES LIKE '%connection_control%' 根本看不到任何变量,所有配置都静默失效。
正确安装顺序:
- 先装主控:
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 LIKE 'connection%';,两行状态都必须是ACTIVE - 确认变量可见:
SHOW VARIABLES LIKE 'connection_control%';,重点看connection_control_failed_connections_threshold(默认 3)和connection_control_min_connection_delay(默认 1000ms)
账户锁定策略(FAILED_LOGIN_ATTEMPTS)和 validate_password 插件强绑定
ALTER USER 'dba'@'192.168.10.50' FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 0.04167; 单独执行会被 MySQL 静默忽略——它不是开关,而是策略绑定参数。必须同时满足三个条件,account_locked = 'Y' 才可能出现在 mysql.user 表中:
- 用户认证插件必须是
caching_sha2_password或mysql_native_password(auth_socket或sha256_password用户永远不锁定) -
FAILED_LOGIN_ATTEMPTS和PASSWORD_LOCK_TIME必须出现在同一条CREATE USER或ALTER USER语句中(顺序无关) -
validate_password插件必须已启用且状态为ACTIVE;否则失败登录根本不会累加计数,错误日志里也搜不到Too many failed login attempts
检查方式:SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'validate_password';
connection_control_failed_connections_threshold 不写进 my.cnf 就不持久
SET GLOBAL connection_control_failed_connections_threshold = 5; 只在当前运行周期有效,MySQL 重启后恢复默认值 3。暴力破解防护一旦中断,等于裸奔。
必须把以下内容写入 my.cnf 的 [mysqld] 段落:
plugin-load-add = connection_control.so connection-control = FORCE_PLUS_PERMANENT connection-control-failed-login-attempts = FORCE_PLUS_PERMANENT connection-control-failed-connections-threshold = 5 connection-control-min-connection-delay = 2000 connection-control-max-connection-delay = 30000
注意:PASSWORD_LOCK_TIME 单位是「天」,锁 1 小时要写 0.04167(1 ÷ 24),写 0 表示永久锁定,且锁定期满后不会自动解锁——必须有一次成功登录,才会重置失败计数并清除 account_locked = 'Y'。











