mysql中用户登录失败次数限制与锁定策略

MySQL 8.0.19+需启用validate_password插件并配置failed_login_attempts与password_lock_time参数,且用户须使用mysql_native_password或caching_sha2_password认证;创建用户时需显式声明FAILED_LOGIN_ATTEMPTS和PASSWORD_LOCK_TIME,解锁用ALTER USER … ACCOUNT UNLOCK。

mysql中用户登录失败次数限制与锁定策略

MySQL 8.0+ 的 failed_login_attemptspassword_lock_time 怎么配

MySQL 8.0.19 起原生支持登录失败锁定,但必须启用 validate_password 插件(即使不校验密码强度),且只对使用 mysql_native_passwordcaching_sha2_password 认证插件的用户生效。

配置需分两步:

  • 全局开启插件:
    INSTALL PLUGIN validate_password SONAME 'validate_password.so';
  • 设置策略参数(在 my.cnf 中或运行时 SET):
    SET PERSIST failed_login_attempts = 3;
    SET PERSIST password_lock_time = 86400;

    (单位:秒;设为 0 表示永久锁定,需手动解锁)

  • 注意:SET PERSIST 写入 mysqld-auto.cnf,重启仍生效;用 SET GLOBAL 则仅当前会话有效

创建带锁定策略的用户时,CREATE USERFAILED_LOGIN_ATTEMPTS 语法怎么写

策略不能全局统一应用到所有用户,必须显式在 CREATE USERALTER USER 里声明。未声明的用户沿用全局默认值(若未设则为 0,即不限制)。

示例(创建一个最多输错 5 次、锁 1 小时的用户):

CREATE USER 'app_user'@'%' IDENTIFIED BY 'p@ssw0rd'
FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 3600;

关键点:

  • FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME 必须同时出现,不能只写一个
  • 若设 PASSWORD_LOCK_TIME UNBOUNDED,表示锁定后永不自动解锁,只能由管理员执行 ALTER USER ... ACCOUNT UNLOCK
  • 该策略仅作用于该用户,与其他用户的锁定状态完全隔离

用户被锁定了,怎么查和解

锁定状态不记录在 mysql.user 表中,而是存在内存中(performance_schemaaccount_status 表),且只在启用相关监控时才可见。

MaxAI

MaxAI

MaxAI.me是一款功能强大的浏览器AI插件,集成了多种AI模型。

下载

更可靠的方式是查 INFORMATION_SCHEMA.USER_ATTRIBUTES(MySQL 8.0.22+):

SELECT User, Host, ATTRIBUTE->>'$.password_lock_time' AS lock_time,
ATTRIBUTE->>'$.failed_login_attempts' AS max_tries
FROM INFORMATION_SCHEMA.USER_ATTRIBUTES
WHERE User = 'app_user';

解锁操作很简单:

ALTER USER 'app_user'@'%' ACCOUNT UNLOCK;

常见误区:

  • DROP USER + CREATE USER 不会重置锁定计数,因为账户元数据未清空(尤其 mysql.user 行还存在)
  • 错误日志里出现 User 'xxx'@'yyy' has been locked due to X failed login attempts 才是真正触发锁定,不是每次输错都记日志
  • 连接池复用连接时,可能因旧连接失效导致误判为“连续失败”,实际锁定是按用户+主机维度统计的

为什么设置了但没生效?几个典型失效场景

最常踩的坑不是配置错,而是环境不满足前提条件:

  • MySQL 版本低于 8.0.19 —— 此功能不存在,SET PERSIST failed_login_attempts 会报错 Unknown system variable
  • 用户认证插件不是 mysql_native_passwordcaching_sha2_password(比如用了 auth_socket 或自定义插件),锁定逻辑直接跳过
  • 客户端连接时用了 --protocol=TCP 但服务端绑定了 skip-networking,导致认证流程绕过账户系统
  • 使用了代理(如 ProxySQL、MaxScale),实际认证发生在代理层,MySQL 本身根本收不到登录请求

验证是否生效最直接的方法:用错误密码反复连接,观察第 N+1 次是否返回 ERROR 3956 (HY000): Account is locked —— 这个错误码才是锁定生效的确凿证据。

https://www.php.cn/faq/1972484.html

发表回复

Your email address will not be published. Required fields are marked *