alter user password expire 是唯一生效方式,直接 update mysql.user 表无效;mysql 8.0 过期逻辑仅识别 alter user 触发的元数据变更,包括 password_last_changed 和内部策略标记。

ALTER USER PASSWORD EXPIRE 是唯一生效方式
直接 UPDATE mysql.user 表的 password_expired 字段无效,哪怕你有 SUPER 权限。MySQL 8.0 的过期逻辑只认 ALTER USER 语句触发的元数据变更,包括 password_last_changed 和内部策略标记。
常见错误操作:
- 用 SET PASSWORD 改密后加 PASSWORD EXPIRE → 报错,语法不支持组合
- 执行 ALTER USER 'u'@'h' PASSWORD EXPIRE; 后立刻用该用户登录,看到 ERROR 1820 (HY000) 是正常现象,但必须用 ALTER USER CURRENT_USER() IDENTIFIED BY 'newpass'; 重置,不能用 SET PASSWORD
-
ALTER USER 'app'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;—— 90 天后过期 -
ALTER USER 'admin'@'localhost' PASSWORD EXPIRE NEVER;—— 显式禁用,慎用 -
ALTER USER 'dev'@'10.%.%.%' PASSWORD EXPIRE;—— 立即过期,适合临时账号
default_password_lifetime 只管新用户
设 SET GLOBAL default_password_lifetime = 90 或在 /etc/my.cnf 的 [mysqld] 段写 default_password_lifetime = 90,只影响后续新建的用户。已有用户(尤其是 root、业务账号)完全不受影响,测评时会因“部分账号未过期”被扣分。
注意:
- 返回值为 0 表示永不过期,等保三级直接不合规
- 返回值为 NULL 表示交由用户级策略决定,不是“默认开启”,别混淆
- MySQL 5.6 及更早版本不支持该变量,执行会报 Unknown system variable
- 查当前值:
SELECT @@default_password_lifetime; - 持久化必须重启:
systemctl restart mysqld(CentOS)或systemctl restart mysql(Ubuntu) - 老用户要逐个处理:
SELECT user, host, password_last_changed FROM mysql.user;,对每条结果手动执行ALTER USER ... PASSWORD EXPIRE INTERVAL 90 DAY;
validate_password 插件必须手动安装且按序配置
MySQL 8.0+ 默认内置 validate_password,但状态是 DISABLED。不装插件,ALTER USER 设置密码时就可能因弱密码报 ERROR 1819,这不是语法错,是校验拦截。
关键点:
- INSTALL PLUGIN validate_password SONAME 'validate_password.so';(Linux)必须执行,SHOW PLUGINS 要看到状态为 ACTIVE
- 参数设置有依赖顺序:先设 policy,再设 length、number_count 等,乱序会导致 SET 失败
- policy = STRONG 强制要求 validate_password.dictionary_file,否则插件初始化失败
- 最小安全基线(MEDIUM):
SET GLOBAL validate_password.policy = MEDIUM;,再设length = 12、mixed_case_count = 1、number_count = 1、special_char_count = 1 - STRONG 模式需额外准备字典文件:
SET PERSIST validate_password.dictionary_file = '/etc/mysql/weak-passwords.txt';,并确保mysql用户有读权限 - 已有弱密码用户不会被自动重检,得手动筛查:
SELECT user, host FROM mysql.user WHERE LENGTH(authentication_string)
过期和强度策略必须同时启用才有效
只设 default_password_lifetime = 90 但没开 validate_password,用户可能设出 Pass123! 这种看似合规实则易爆破的密码;反过来,只开强度校验却不设过期,密码长期不换照样违规。两者是叠加生效,不是二选一。
容易被忽略的细节:
- password_history 和 password_reuse_interval 在 MySQL 8.0.29+ 才原生支持,低版本只能靠外部工具补位
- ALTER USER 设置密码时若含用户名(如 'root')、主机名(如 'localhost')或常见弱词('admin'、'123456'),即使满足长度和字符类型也会被拒绝
- PASSWORD EXPIRE 后首次登录只能执行 ALTER USER CURRENT_USER() IDENTIFIED BY,其他任何语句(包括 SELECT 1)都会报错











