如何设定MySQL的密码过期策略以符合安全合规要求

作者:袖梨 2026-06-24
MySQL密码过期策略必须显式设为非零值(如90),因默认default_password_lifetime=0等同永不过期,不满足等保三级要求;需通过配置文件永久设置全局策略,并为所有现有用户单独执行ALTER USER指定过期时间。

MySQL密码过期策略必须显式设为非零值(如90),默认default_password_lifetime = 0等同于永不过期,直接不满足等保三级要求。

查当前全局策略是否生效

先确认实例当前状态,避免误判策略已启用:

  • SELECT @@global.default_password_lifetime; —— 返回0说明未启用,返回NULL表示交由用户级策略决定,返回正整数(如90)才真正生效
  • SHOW VARIABLES LIKE 'default_password_lifetime'; 必须在mysql库下执行,部分客户端连接时默认库非mysql会导致查不到
  • MySQL 5.6 及更早版本不支持该变量,执行会报错 Unknown system variable 'default_password_lifetime'

全局策略必须写配置文件重启生效

仅靠SET GLOBALSET PERSIST不能替代配置文件修改,否则重启后丢失,且易遗漏:

  • 编辑/etc/my.cnf/etc/mysql/mysql.conf.d/mysqld.cnf,在[mysqld]段添加:default_password_lifetime = 90
  • systemctl restart mysqld(RHEL/CentOS)或systemctl restart mysql(Ubuntu/Debian)
  • 别用SET PERSIST default_password_lifetime = 90——它写入mysqld-auto.cnf,但该文件可能被运维脚本覆盖或忽略,不可靠
  • 设为0NULL都表示禁用,二者语义不同:0是硬性关闭,NULL是让渡控制权给用户级设置

已有用户必须逐个执行ALTER USER

全局设置只影响新用户或后续改密的账号,老用户不会自动继承,测评时会被判定为“部分账号未过期”而扣分:

  • ALTER USER 'app_user'@'%' PASSWORD EXPIRE INTERVAL 90 DAY; —— 强制该账号从password_last_changed起算90天后过期
  • ALTER USER 'root'@'localhost' PASSWORD EXPIRE INTERVAL 30 DAY; —— 高权限账号建议周期更短
  • ALTER USER 'svc_account'@'%' PASSWORD EXPIRE NEVER; —— 仅限服务类账号,且需配套审计日志与访问控制
  • 执行前务必查现状:SELECT user, host, password_last_changed, password_lifetime FROM mysql.user;,重点关注password_lifetime是否为90而非NULL0

密码过期后登录失败的真实错误是ERROR 1820 (HY000)

不是所有“登录失败”都是密码过期,混淆会导致排查方向错误:

  • 真正由过期触发的错误只有一种:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
  • ERROR 1045 (28000) 是认证失败,优先查password_expired字段是否为'Y',再查账号锁定或主机限制
  • 过期用户能建立连接,但除ALTER USER ... IDENTIFIED BY外,任何语句(包括SELECT 1)都会被拒
  • 应用连接池若缓存了旧连接,可能在连接复用时突然报错,需确认池配置支持自动重连+重认证(如HikariCP的connection-init-sql

最常被忽略的是:password_last_changed时间戳不会因修改default_password_lifetime而更新,一个创建于2025年1月的账号,在2026年6月把全局策略设为90,它很可能已经“逻辑过期”,但MySQL不会主动通知,只会在下次登录时抛ERROR 1820

相关文章

精彩推荐