Oracle 11g 引入默認密碼策略:PASSWORD_LIFE_TIME=180 天、FAILED_LOGIN_ATTEMPTS=10 次。未感知此變更的系統會在部署 ~6 個月後集中爆發「ORA-28000: 賬號被鎖定」或「ORA-28002: 密碼即將過期」故障。本文提供根因、影響、解決步驟、驗證腳本及長效機制。
| 策略參數 | 默認值 | 觸發條件 | 錯誤碼 |
|---|---|---|---|
| PASSWORD_LIFE_TIME | 180 天 | 密碼超過 180 天未修改 | ORA-28002 (預警 7 天) → ORA-28001 (過期) |
| FAILED_LOGIN_ATTEMPTS | 10 次 | 連續 10 次密碼錯誤 | ORA-28000: 賬號被鎖定 |
這兩個參數定義在 DEFAULT 設定檔中,無論 RESOURCE_LIMIT 參數為 TRUE/FALSE 都生效。
SELECT username, profile FROM dba_users;
SELECT resource_name, limit
FROM dba_profiles
WHERE profile = 'DEFAULT'
AND resource_name IN ('PASSWORD_LIFE_TIME', 'FAILED_LOGIN_ATTEMPTS', 'PASSWORD_GRACE_TIME', 'PASSWORD_REUSE_TIME', 'PASSWORD_REUSE_MAX');
SELECT username,
expiry_date,
ROUND(expiry_date - SYSDATE) AS days_left,
account_status
FROM dba_users
WHERE profile = 'DEFAULT'
AND expiry_date < SYSDATE + 30 -- 未來 30 天過期
ORDER BY expiry_date;
SELECT username, lock_date, account_status
FROM dba_users
WHERE account_status LIKE '%LOCK%';
-- 1. 密碼永不過期
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
-- 2. 登錄失敗不鎖定 (或設大值如 100)
ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED;
-- 3. 密碼寬限期無限制 (過期後仍可登錄修改密碼)
ALTER PROFILE DEFAULT LIMIT PASSWORD_GRACE_TIME UNLIMITED;
-- 4. 驗證修改
SELECT resource_name, limit
FROM dba_profiles
WHERE profile = 'DEFAULT'
AND resource_name IN ('PASSWORD_LIFE_TIME', 'FAILED_LOGIN_ATTEMPTS', 'PASSWORD_GRACE_TIME');
預期輸出:
RESOURCE_NAME LIMIT
-------------------------- --------------------
PASSWORD_LIFE_TIME UNLIMITED
FAILED_LOGIN_ATTEMPTS UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED
-- 創建應用專用設定檔
CREATE PROFILE app_service_profile LIMIT
PASSWORD_LIFE_TIME UNLIMITED
FAILED_LOGIN_ATTEMPTS 50
PASSWORD_GRACE_TIME 30
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
SESSIONS_PER_USER UNLIMITED
CPU_PER_SESSION UNLIMITED
CONNECT_TIME UNLIMITED
IDLE_TIME 60;
-- 分配給服務賬號
ALTER USER app_user PROFILE app_service_profile;
-- 以 SYSDBA 登錄
SQLPLUS / AS SYSDBA
-- 修改密碼 (即使相同值也會重置過期時間)
ALTER USER scott IDENTIFIED BY tiger; -- 原密碼
-- 或
ALTER USER scott IDENTIFIED BY new_strong_password;
ALTER USER scott ACCOUNT UNLOCK;
ALTER USER scott IDENTIFIED BY tiger; -- 解鎖後必須重置密碼
SET SERVEROUTPUT ON
DECLARE
CURSOR c_expired IS
SELECT username FROM dba_users
WHERE profile = 'DEFAULT'
AND (account_status IN ('EXPIRED', 'EXPIRED(GRACE)')
OR expiry_date < SYSDATE + 7);
CURSOR c_locked IS
SELECT username FROM dba_users
WHERE account_status LIKE '%LOCK%';
BEGIN
FOR r IN c_expired LOOP
EXECUTE IMMEDIATE 'ALTER USER ' || r.username || ' IDENTIFIED BY VALUES ''' ||
(SELECT password FROM dba_users WHERE username = r.username) || '''';
DBMS_OUTPUT.PUT_LINE('Reset password expiry for: ' || r.username);
END LOOP;
FOR r IN c_locked LOOP
EXECUTE IMMEDIATE 'ALTER USER ' || r.username || ' ACCOUNT UNLOCK';
EXECUTE IMMEDIATE 'ALTER USER ' || r.username || ' IDENTIFIED BY VALUES ''' ||
(SELECT password FROM dba_users WHERE username = r.username) || '''';
DBMS_OUTPUT.PUT_LINE('Unlocked and reset: ' || r.username);
END LOOP;
END;
/
-- 注意:IDENTIFIED BY VALUES 需密碼哈希值,11g+ 需從 USER$ 獲取或重置為已知密碼
-- 每日巡檢腳本輸出
SELECT 'PASSWORD_EXPIRY_WARNING' AS check_type, username,
ROUND(expiry_date - SYSDATE) AS days_left
FROM dba_users
WHERE profile = 'DEFAULT'
AND expiry_date BETWEEN SYSDATE AND SYSDATE + 14
UNION ALL
SELECT 'ACCOUNT_LOCKED', username, NULL
FROM dba_users
WHERE account_status LIKE '%LOCK%';
DBA_PROFILES、DBA_USERS 歸檔| 版本 | 默認策略 | 備註 |
|---|---|---|
| 10g 及以前 | 無默認密碼過期/鎖定 | DEFAULT 設定檔參數均為 UNLIMITED |
| 11g / 12c / 18c / 19c | PASSWORD_LIFE_TIME=180, FAILED_LOGIN_ATTEMPTS=10 | 安裝時自動應用 |
| 21c+ | 同 11g | 建議安裝後立即按安全基線調整 |
Oracle 11g+ 默認密碼策略是「隱形定時炸彈」。安裝即調整 DEFAULT 設定檔、建立專用設定檔、實施自動化巡檢、構建密碼輪換機制,四步建立長效免疫體系,徹底消除 ORA-28000/28001/28002 突發風險。