首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 5.6/5.7 用戶密碼過期策略與賬戶鎖定機制完整指南:PCI DSS 合規、自動輪換、安全基線

     編輯:MySQL 資料庫相關知識

PCI DSS 要求用戶每 90 天輪換密碼。MySQL 5.6.6+ 引入 password_expired、5.7.4+ 引入 default_password_lifetime 全局策略、5.7.8+ 引入賬戶鎖定 ACCOUNT LOCK/UNLOCK。本文系統梳理密碼過期策略配置、自動化輪換、賬戶生命週期管理、合規審計全流程。

一、密碼過期機制演進

版本特性配置方式
5.6.6+password_expired 列 (mysql.user)ALTER USER ... PASSWORD EXPIRE
5.7.4+default_password_lifetime 全局變量my.cnf / SET GLOBAL
5.7.8+賬戶鎖定 ACCOUNT LOCK/UNLOCKCREATE/ALTER USER ... ACCOUNT LOCK
8.0+密碼歷史、重用間隔、驗證插件password_history, password_reuse_interval

二、單用戶密碼過期操作

-- 立即過期 (下次登入強制修改)
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE;

-- 用戶登入後僅能執行 SET PASSWORD
SET PASSWORD = PASSWORD('NewStrongPass123!');
-- 或 8.0+
ALTER USER USER() IDENTIFIED BY 'NewStrongPass123!';

過期用戶行為

  • 可正常連接、認證通過
  • 執行任何查詢報錯:ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
  • 修改密碼後恢復正常權限

三、全局密碼壽命策略

1. 配置文件永久生效

[mysqld]
# 90 天過期 (PCI DSS)
default_password_lifetime=90

# 永不過期 (內部系統)
default_password_lifetime=0

2. 運行時動態調整

SET GLOBAL default_password_lifetime = 90;
SET PERSIST default_password_lifetime = 90;  -- 8.0+ 持久化到 mysqld-auto.cnf

3. 用戶級覆蓋全局策略

-- 用戶專屬 30 天
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE INTERVAL 30 DAY;

-- 用戶永不過期
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE NEVER;

-- 用戶遵循全局策略
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE DEFAULT;

四、賬戶鎖定與解鎖 (5.7.8+)

-- 創建鎖定賬戶
CREATE USER 'furrywall'@'localhost' IDENTIFIED BY 'Pass123!' ACCOUNT LOCK;

-- 鎖定現有賬戶
ALTER USER 'furrywall'@'localhost' ACCOUNT LOCK;
-- 錯誤: ERROR 3118 (HY000): Access denied for user 'furrywall'@'localhost'. Account is locked.

-- 解鎖
ALTER USER 'furrywall'@'localhost' ACCOUNT UNLOCK;

五、自動化密碼輪換體系

1. 掃描即將過期用戶 (每日定時任務)

#!/bin/bash
# check_password_expiry.sh
mysql -uroot -p -e "
SELECT User, Host, 
       password_last_changed,
       IF(default_password_lifetime=0, 'NEVER', 
          DATE_ADD(password_last_changed, INTERVAL default_password_lifetime DAY)
       ) AS expiry_date
FROM mysql.user
WHERE password_expired = 'N'
  AND default_password_lifetime > 0
  AND DATE_ADD(password_last_changed, INTERVAL default_password_lifetime DAY) < DATE_ADD(NOW(), INTERVAL 7 DAY);
" | mail -s "MySQL 密碼即將過期預警" dba@company.com

2. 強制輪換流程 (應用配合)

  1. DBA 執行 ALTER USER ... PASSWORD EXPIRE
  2. 應用連接池捕獲 1820 錯誤 → 彈出修改密碼頁面 / 調用密碼修改 API
  3. 應用執行 SET PASSWORD / ALTER USER
  4. 驗證新密碼可用 → 更新配置中心/密碼保險箱

3. 密碼複雜度驗證 (validate_password 組件)

INSTALL COMPONENT 'file://component_validate_password';
-- 或 5.7: INSTALL PLUGIN validate_password SONAME 'validate_password.so';

SET GLOBAL validate_password.length=12;
SET GLOBAL validate_password.mixed_case_count=1;
SET GLOBAL validate_password.number_count=1;
SET GLOBAL validate_password.special_char_count=1;
SET GLOBAL validate_password.policy=STRONG;

六、合規審計報表

-- 密碼合規狀態全景
SELECT 
    User, Host,
    password_last_changed,
    password_lifetime,
    password_expired,
    account_locked,
    CASE 
        WHEN password_lifetime = 0 THEN 'NEVER_EXPIRE'
        WHEN password_expired = 'Y' THEN 'EXPIRED'
        WHEN DATE_ADD(password_last_changed, INTERVAL password_lifetime DAY) < NOW() THEN 'OVERDUE'
        WHEN DATE_ADD(password_last_changed, INTERVAL password_lifetime DAY) < DATE_ADD(NOW(), INTERVAL 30 DAY) THEN 'EXPIRING_SOON'
        ELSE 'COMPLIANT'
    END AS compliance_status
FROM mysql.user
WHERE User NOT IN ('mysql.sys', 'mysql.session')
ORDER BY compliance_status, User;

七、避坑指南

坑 1:default_password_lifetime 不影響現有用戶的 password_last_changed
修改全局策略後,現有用戶按原 password_last_changed 計算過期時間,新用戶按新策略
坑 2:應用連接池不處理 1820 錯誤導致業務中斷
必須在連接池/數據源層攔截 1820,觸發密碼修改流程
坑 3:PASSWORD() 函數 8.0 已移除
使用 ALTER USER ... IDENTIFIED BY 或 SET PASSWORD = 'plaintext' (8.0 自動哈希)
坑 4:賬戶鎖定不影響已建立的連接
需配合 KILL 斷開現有會話
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved