Oracle数据库的账户安全问题往往从密码管理开始。不少运维人员都遇到过这样的情况:应用服务器重启后数据库连接突然全部报错,排查半天才发现是某个账号密码输错次数太多触发了锁定机制;或者账号用到一半提示ORA-28001密码过期,业务被迫中断。这些现象背后都指向同一个东西——profile中的密码策略配置。理解并合理设置这些参数,是Oracle日常运维的基本功。

一、profile是什么:密码策略的载体
Oracle中所有的密码策略和资源限制都不是直接挂在用户上的,而是通过profile(配置文件)这个对象来承载。每个用户创建时都会关联一个profile,如果不指定,默认使用DEFAULT这个profile。密码相关的所有规则,比如多少次输错密码后锁定、锁定多久、密码多久过期、过期后有多长宽限期,全部定义在profile里。
查看系统当前的profile和用户关联关系,可以用下面的SQL:
-- 查看所有profile SELECT * FROM dba_profiles ORDER BY profile, resource_type; -- 查看用户关联的profile SELECT username, profile FROM dba_users WHERE username = 'SCOTT';
查询结果里resource_type为PASSWORD的行就是密码策略,为KERNEL的行是资源限制(如会话数、CPU时间),本文重点关注前者。需要注意的是,如果初始化参数resource_limit设置为FALSE,KERNEL类的资源限制不生效,但密码策略始终生效,这也是很多人容易混淆的一点:密码策略不受resource_limit控制,改这个参数对锁定和过期行为没有任何影响。
二、账户锁定相关参数详解与配置
账户锁定由两个参数配合完成。FAILED_LOGIN_ATTEMPTS指定允许的最大登录失败次数,默认值是10次(11g及以后版本),超过这个次数账户自动锁定;PASSWORD_LOCK_TIME指定锁定持续时间,默认1天,单位是天。锁定分为两种情形:连续登录失败达到阈值触发的锁定会在锁定时间结束后自动解锁,而DBA手动执行的锁定则必须手动解锁。
典型配置示例:
-- 创建一个宽松的profile:失败20次锁定,锁30分钟后自动解锁 CREATE PROFILE app_profile LIMIT FAILED_LOGIN_ATTEMPTS 20 PASSWORD_LOCK_TIME 30/1440; -- 30分钟换算成天 -- 将profile应用到用户 ALTER USER app_user PROFILE app_profile; -- 手动锁定与解锁 ALTER USER app_user ACCOUNT LOCK; ALTER USER app_user ACCOUNT UNLOCK;
有一点要特别提醒:PASSWORD_LOCK_TIME写小数时用除法表达式比直接写0.02更清晰,30/1440表示30分钟,可读性好且不容易算错。另外,有些场景下运维希望锁定后立刻解锁而不用等到锁定时间结束,直接执行ACCOUNT UNLOCK即可,Oracle不会因为你还在锁定期内而拒绝解锁。
如果某些纯内部测试库想彻底关闭锁定机制(不推荐在生产环境这样做),可以把FAILED_LOGIN_ATTEMPTS设为UNLIMITED。但这样做会失去对暴力破解的基本防御能力,攻击者可以无限次尝试密码,风险自负。
三、密码有效期与复杂度管理
除了锁定,密码策略还包括有效期和复用规则。PASSWORD_LIFE_TIME指定密码有效天数,默认180天,到期后登录会报ORA-28001;PASSWORD_GRACE_TIME指定宽限期天数,默认7天,宽限期内登录成功但会收到修改密码的警告,宽限期一过账号彻底失效。PASSWORD_REUSE_TIME和PASSWORD_REUSE_MAX控制密码复用,前者要求间隔多少天才能重用旧密码,后者要求改过多少次密码后才能重用,两者设置一个为UNLIMITED另一个为具体值即可生效。
-- 密码90天有效,宽限期7天,同一密码180天内不能重复使用 ALTER PROFILE app_profile LIMIT PASSWORD_LIFE_TIME 90 PASSWORD_GRACE_TIME 7 PASSWORD_REUSE_TIME 180 PASSWORD_REUSE_MAX UNLIMITED;
密码复杂度通过PASSWORD_VERIFY_FUNCTION参数挂接一个校验函数实现。Oracle自带一个示例脚本utlpwdmg.sql,位于rdbms/admin目录下,执行后会创建verify_function并自动修改DEFAULT profile。如果想自定义规则,比如要求密码至少12位且必须包含大小写字母和数字,可以自己写函数:
CREATE OR REPLACE FUNCTION verify_pwd
(username VARCHAR2, password VARCHAR2, old_password VARCHAR2)
RETURN BOOLEAN IS
BEGIN
IF LENGTH(password) < 12 THEN
RETURN FALSE;
END IF;
IF NOT REGEXP_LIKE(password, '[A-Z]') THEN
RETURN FALSE;
END IF;
IF NOT REGEXP_LIKE(password, '[a-z]') THEN
RETURN FALSE;
END IF;
IF NOT REGEXP_LIKE(password, '[0-9]') THEN
RETURN FALSE;
END IF;
RETURN TRUE;
END;
/
ALTER PROFILE app_profile LIMIT PASSWORD_VERIFY_FUNCTION verify_pwd;
函数必须返回BOOLEAN,返回FALSE时修改密码操作会被拒绝并报ORA-20000之类的错误。取消校验只需把参数设为NULL。
四、常见问题排查与最佳实践建议
遇到账户被锁,第一步是确认锁定原因。查询dba_users的account_status字段,OPEN表示正常,LOCKED表示失败次数超限锁定,LOCKED(TIMED)表示处于定时锁定期内,EXPIRED表示密码过期,EXPIRED(GRACED)表示处于宽限期。结合alert日志中的登录失败记录,基本能定位是应用配置错密码还是遭遇了扫描攻击。
-- 检查账号状态
SELECT username, account_status, lock_date, expiry_date,
profile, created
FROM dba_users
WHERE username = 'APP_USER';
关于是否直接修改DEFAULT profile,建议谨慎。DEFAULT profile影响所有未显式指定profile的用户,包括数据库内部维护的账号,改动前最好先梳理清楚受影响的用户清单。更稳妥的做法是创建独立的业务profile,按业务重要性分级配置策略:核心业务账号可以严格一些,测试账号适当放宽。
最后总结几条实践经验:改密码策略前先查当前值并留存记录;应用连接池配置的密码务必与数据库侧同步修改,避免改完密码应用立即触发失败锁定;定期审计dba_users中状态异常的账号;对暴露在外的数据库启用密码复杂度校验,配合监听器层面的IP白名单,多层防御远比单一策略可靠。把锁定阈值设得既能拦截暴力破解又不至于因个别误输入就锁死业务,通常失败次数设在10到20次之间是比较均衡的选择。
Oracle密码策略账户锁定FAILED_LOGIN_ATTEMPTS修改时间:2026-09-12 23:02:31