FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 必须配对设置在同一条 ALTER PROFILE 语句中,否则账户可能永久锁定;PASSWORD_LOCK_TIME 单位为天,设为1/24表示锁定1小时,未设置时默认为UNLIMITED(永久锁定)。
只设 failed_login_attempts 不设 password_lock_time,账户会被锁定但永远不解锁——这是生产环境最常踩的坑。oracle 默认 password_lock_time 是 0(即永久锁定),不是“1小时”或“1天”。
FAILED_LOGIN_ATTEMPTS 控制失败几次后触发锁定,值为 5 或 10 较常见PASSWORD_LOCK_TIME 单位是“天”,设为 1/24 表示锁定 1 小时,1/1440 表示锁定 1 分钟PASSWORD_LOCK_TIME 为 UNLIMITED,需 DBA 手动执行 ALTER USER ... ACCOUNT UNLOCK 才能恢复直接在 DEFAULT profile 上改 FAILED_LOGIN_ATTEMPTS,等于给所有未显式指定 profile 的用户(包括 SYS、SYSTEM、DBSNMP)统一上锁——某次误操作导致监控账号被锁,Zabbix 告警全丢。
CREATE PROFILE app_login_limit LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1/24;
SELECT username, profile FROM dba_users WHERE username = 'APP_USER';
ALTER USER app_user PROFILE app_login_limit;
dba_users.account_status 和登录行为光看 dba_profiles 里的 limit 值没用,必须验证实际登录时的行为。很多 DBA 改完就以为好了,结果攻击者仍在暴力扫。
ALTER USER testuser ACCOUNT UNLOCK;
ORA-01017: invalid username/password 后再连是否报 ORA-28000: the account is locked
SELECT username, account_status, lock_date FROM dba_users WHERE username = 'TESTUSER'; —— LOCKED 或 LOCKED(TIMED) 才算成功lock_date 字段有值,且 account_status 显示 LOCKED(TIMED),说明 PASSWORD_LOCK_TIME 生效;若为 LOCKED(无 TIMED),说明 PASSWORD_LOCK_TIME 是 0 或未设数据库层的 FAILED_LOGIN_ATTEMPTS 只拦 SQL 登录,拦不住绕过数据库直连监听器的扫描。去年某客户被扫出 200+ 个弱密码账户,源头是监听器暴露在公网。
$ORACLE_HOME/network/admin/listener.ora,启用节点验证:VALID_NODE_CHECKING_REGISTRATION_LISTENER = ON
REGISTRATION_INVITED_NODES_LISTENER = (localhost,192.168.10.0/24)
lsnrctl reload(无需重启数据库实例)lsnrctl status 输出中应含 Security: ON 和 Valid Node Checking: ON