游乐游手机版
首页/数据库/文章详情

MySQL防止非法用户暴力破解密码的配置方法

时间:2026-07-18 18:15
MySQL防暴力破解需同时配置FAILED_LOGIN_ATTEMPTS(失败次数阈值)和PASSWORD_LOCK_TIME(锁定时间),依赖validate_password插件,且仅对caching_sha2_password等认证插件生效。锁定期满后需成功登录方可重置失败计数。还需安装connection_control及配套组件,配合网络层IP白名
首先给出明确结论:要为 MySQL 配置防暴力破解机制,并非简单设置几个参数就能生效。**FAILED_LOGIN_ATTEMPTS** 和 **PASSWORD_LOCK_TIME** 这两个参数必须成对使用,并且依赖 `validate_password` 插件处于启用状态。此外,它们仅对采用 `caching_sha2_password` 或 `mysql_native_password` 认证插件的用户有效;单独配置其中一个参数等同于未设。参数单位是天,锁定到期后不会自动解除,必须有一次成功的登录才能重置失败计数。

MySQL如何配置以防止非法用户暴力破解数据库密码?

FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 必须成对设置

如果单独执行 ALTER USER 'u'@'%' FAILED_LOGIN_ATTEMPTS 3,MySQL 会直接忽略该指令,不会产生任何效果。这两个参数是硬性捆绑的——缺一不可,排列顺序无关紧要,但缺少任意一个就会完全失效。

  • 新建用户时,必须一次性完整书写:CREATE USER 'api'@'%' IDENTIFIED WITH caching_sha2_password BY 'pwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.04167(锁定1小时)
  • 对已有用户进行修改时,连认证插件也必须一同更换:ALTER USER 'api'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.04167
  • PASSWORD_LOCK_TIME 的单位为"天",因此锁定5分钟需要写成 0.00347(5 ÷ 1440)。如果设为 0,表示永久锁定,而非"不锁定"
  • 锁定期满后,不会自动解锁——必须有一次成功的登录才能重置失败计数,同时清除 account_locked = 'Y' 的状态

validate_password 插件不是可选,而是必需

即使参数书写完整、认证插件也匹配,但如果 `validate_password` 未被启用,失败登录根本不会累积计数。你在 `mysql.user` 表中永远看不到 `account_locked = 'Y'`,错误日志中也无法搜索到 `Too many failed login attempts` 这条信息。

  • 检查是否激活:SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'validate_password',状态必须为 `ACTIVE`
  • 启用方式有两种:在配置文件中添加 plugin_load_add = validate_password.so 后重启;或者直接执行 INSTALL PLUGIN validate_password SONAME 'validate_password.so'
  • 启用后会自动激活密码强度策略(例如 `validate_password.length`),这可能会影响已有的创建用户脚本,建议提前做好验证

connection_control 插件必须安装两个组件才生效

只安装 `CONNECTION_CONTROL` 并不足够——它负责延时逻辑,但失败计数依赖于配套组件 `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'
  • connection_control_failed_connections_threshold 参数如果不写入 `my.cnf` 则不会持久化——通过 `SET GLOBAL` 设置后,重启即失效
  • 注意单位:connection_control_min_connection_delay 的单位是毫秒,而非秒;`max` 值设置过高(例如 60000)可能会卡死连接池,引发 `Too many connections`
  • 'root'@'localhost' 和所有本地连接默认被绕过,这是设计的正常行为,并非漏洞

别信“%”通配符,IP 白名单才是第一道墙

只要 `3306` 端口对公网开放,并且用户的 Host 设置为 `'%'`,暴力破解的风险就始终真实存在。MySQL 自身的账户锁定仅仅是最外层防线,不能替代网络隔离。

  • 禁止远程 root 登录:DELETE FROM mysql.user WHERE user='root' AND host!='localhost',然后执行 FLUSH PRIVILEGES
  • 业务账号必须绑定具体的 IP 或内网段:CREATE USER 'webapp'@'192.168.10.50' IDENTIFIED BY 'strong_pwd'
  • 云环境务必在安全组层面只放行应用服务器的内网 IP;物理机使用 `iptables` 或 `ufw` 严格限制源地址
  • bind-address 绝不可设为 `0.0.0.0`,应优先设为 `127.0.0.1` 或内网地址
真正起效的从来不是单点配置,而是 `caching_sha2_password` + `validate_password` + `FAILED_LOGIN_ATTEMPTS/PASSWORD_LOCK_TIME` 三者同时在线,再加上 `CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS` 的延时压制以及防火墙层面的 IP 白名单——缺少任何一环,攻击者都可能找到绕过途径。
来源:https://www.php.cn/faq/2814804.html
上一篇如何用MongoDB聚合管道提高数据查询效率的方法 下一篇MySQL正则表达式高级查询实用技巧详解与实例
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
SQL嵌套查询与窗口函数结合使用技巧
数据库 · 2026-07-18

SQL嵌套查询与窗口函数结合使用技巧

窗口函数不能直接用于WHERE、GROUPBY或HAVING,需先放入子查询或CTE计算,再在外层引用。典型错误如WHERE中写ROW_NUMBER(),需先用子查询生成编号再过滤。窗口函数排序必须显式写在OVER子句中,CTE比嵌套子查询更可靠。

phpMyAdmin导出的Laravel SQL文件生产环境报错原因
数据库 · 2026-07-18

phpMyAdmin导出的Laravel SQL文件生产环境报错原因

当使用phpMyAdmin工具导出SQL文件时出现报错,最常见的主要原因包括MySQL版本不匹配(例如8 0特有语法用于5 7)、时区设置语句导致错误、字符集编码不一致等。推荐的解决方法主要包括:注意需要仔细检查文件头部注释内容尤其是版本号,避免使用高版本特有语法,请务必删除SETtime_zone这行语句,并将字符集统一设置为utf8mb4编。

MySQL读已提交RC隔离级别减少间隙锁死锁原理
数据库 · 2026-07-18

MySQL读已提交RC隔离级别减少间隙锁死锁原理

RC隔离级别默认不加间隙锁,只对命中行加记录锁,通过半一致性读减少锁竞争,且执行后立即释放未命中行的锁,降低了死锁概率。RR隔离级别默认加临键锁,扫描范围全加锁并保持到事务结束,死锁风险更高。但RC在唯一键冲突等场景下仍可能隐式加间隙锁。

MySQL批量更新表中特定字段值的方法
数据库 · 2026-07-18

MySQL批量更新表中特定字段值的方法

批量更新MySQL表字段,推荐使用CASEWHEN、INSERT…ONDUPLICATEKEYUPDATE或UPDATEJOIN,避免逐行循环。注意语法正确、类型统一,单次更新控制500-1000行,超10万行需分片提交并显式提交事务。

phpMyAdmin查询窗口为何无法执行超30秒SQL
数据库 · 2026-07-18

phpMyAdmin查询窗口为何无法执行超30秒SQL

phpMyAdmin超时源于$cfg[ ExecTimeLimit ]默认30秒,修改php ini无效,需在config inc php中设为0。MySQL的max_allowed_packet不足也会导致假性超时,需调整配置并重启服务。命令行导入可绕过Web层限制。