為滿足 PCI DSS (支付卡產業資料安全標準) 要求「每 90 天變更密碼」,MySQL 5.6.6+ 引入密碼過期機制,5.7.4+ 強化為全域自動策略,5.7.8+ 新增帳號鎖定功能。本文系統整合版本演進、配置策略、自動化運維與最佳實踐。
| 版本 | 關鍵特性 | 應用場景 |
|---|---|---|
| 5.6.6 | password_expired 欄位 (Y/N)、ALTER USER ... PASSWORD EXPIRE | 手動單一帳號過期控制 |
| 5.7.4 | 全域變數 default_password_lifetime、ALTER USER ... PASSWORD EXPIRE INTERVAL N DAY | 自動化全域/個別過期策略 |
| 5.7.6 | ALTER USER USER() IDENTIFIED BY ... 當前用戶修改密碼 | 應用端自我服務修改密碼 |
| 5.7.8 | 帳號鎖定 ACCOUNT LOCK/UNLOCK、CREATE USER ... ACCOUNT LOCK | 離職管控、緊急凍結、自動化合規 |
mysql.user 表中 password_expired 欄位 (ENUM 'Y','N') 控制帳號狀態:
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement不影響已建立的連線 (既有 Session)。
-- 立即要求 testuser 修改密碼
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE;
-- 用戶登入後必須執行
SET PASSWORD = PASSWORD('NewComplexPass123!');
-- 或 5.7.6+
ALTER USER USER() IDENTIFIED BY 'NewComplexPass123!';
-- 解除過期狀態 (管理員操作)
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE NEVER;
配置檔永久生效 (/etc/my.cnf):
[mysqld]
# 所有用戶密碼 90 天自動過期 (PCI DSS 標準)
default_password_lifetime=90
# 永不過期 (預設值,可不寫)
default_password_lifetime=0
運行時動態調整 (需 SUPER 權限,重啟失效):
SET GLOBAL default_password_lifetime = 90;
SET GLOBAL default_password_lifetime = 0; -- 關閉
MySQL 從啟動時間點開始計算,而非密碼最後修改時間 (5.7.4-5.7.10 行為),5.7.11+ 改為以密碼最後修改時間計算。
-- 設定特定用戶 30 天過期 (優先於全域 90 天)
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE INTERVAL 30 DAY;
-- 禁用該用戶過期 (忽略全域策略)
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE NEVER;
-- 恢復使用全域預設策略
ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE DEFAULT;
注意:INTERVAL 單位為 **天 (DAY)**,不支援小時/月。
資料庫層面無主動通知功能,需應用層或排程腳本配合:
-- 查詢即將過期/已過期帳號 (假設 7 天內預警)
SELECT User, Host, password_expired, password_last_changed
FROM mysql.user
WHERE password_expired = 'N'
AND password_last_changed < DATE_SUB(NOW(), INTERVAL 83 DAY); -- 90-7=83
搭配 cron + 腳本 (Python/Shell) 發送郵件/企業微信/Slack 通知用戶及管理員。
密碼過期僅限制「查詢前必改密碼」,帳號仍可登入。鎖定則**完全禁止認證**:
-- 建立鎖定帳號
CREATE USER 'contractor'@'%' IDENTIFIED BY 'TempPass123!' ACCOUNT LOCK;
-- 鎖定現有帳號 (離職、異常)
ALTER USER 'contractor'@'%' ACCOUNT LOCK;
-- 登入嘗試報錯:ERROR 3118 (HY000): Access denied for user 'contractor'@'%'. Account is locked.
-- 解鎖恢復
ALTER USER 'contractor'@'%' ACCOUNT UNLOCK;
鎖定 vs 過期對比:
| 特性 | 密碼過期 | 帳號鎖定 |
|---|---|---|
| 登入能力 | 可登入 | 完全禁止登入 |
| 查詢能力 | 改密碼前不可查詢 | 完全不可查詢 |
| 適用場景 | 定期輪換、合規要求 | 離職、安全事件、臨時帳號 |
| 自動化 | 支援全域/個別策略 | 需外部腳本觸發 |
default_password_lifetime=90 寫入 my.cnf。PASSWORD EXPIRE NEVER,並記錄在台帳。password_last_changed,提前 7/3/1 天通知。ALTER USER ... ACCOUNT LOCK,不可僅停用應用層帳號。log_statement=ddl 或審計插件記錄所有 ALTER USER 操作。password_last_changed 計算。MySQL 密碼過期與帳號鎖定提供了從「合規驅動」到「安全管控」的完整工具鏈。核心在於:**全域策略自動化 (default_password_lifetime) + 例外精細管控 (INTERVAL/NEVER/LOCK) + 外部自動化通知/離職聯動**。升級至 5.7.11+ 避免重啟重置 Bug,並建立完整運維 SOP,才能真正落地 PCI DSS 要求。