用途
本故障排除指南旨在提供有关如何跟踪因 ora-1017 失败(在数据库身份验证期间登录被拒绝)的可疑登录的信息。请注意,在大多数情况下,恶意来源并不是登录失败的原因。它可能只是用户名或密码中的拼写错误、其中包含无效密码的 cron 作业,甚至是配置错误的 Oracle 客户端程序(例如,请参阅引用的注释 267401.1)。无论如何,这些不成功的连接尝试可能会很麻烦,特别是当密码管理策略对 failed_login_attempts 有限制并导致 ora-28000“帐户已锁定”错误时。
排错步骤
检查 DBA_USERS
如果用户的 ACCOUNT_STATUS 为 LOCKED,这意味着该帐户已被 DBA 执行 ALTER USER &username ACCOUNT LOCK; 锁定。如果 ACCOUNT_STATUS 为 LOCKED(TIMED),这意味着它因超过允许的 FAILED_LOGIN_ATTEMPTS 次数而被锁定,即使 PASSWORD_LOCK_TIME 设置为无限制,也是如此。 帐户永远不会因密码过期而被锁定。
在帐户实际锁定之前,您可以通过检查 USER$.LCOUNT 列来检查到目前为止登录尝试失败的次数:
select name,lcount from user$ where name='&USERNAME';
审计为成功的登录
首先通过设置 audit_trail = db 建立标准审计并执行:
AUDIT SESSION WHENEVER NOT SUCCESSFUL;
比如从“上周”开始登录失败的审核记录如下:
select username,
os_username,
userhost,
client_id,
trunc(timestamp),
count(*) failed_logins
from dba_audit_trail
where returncode=1017 and --1017 is invalid username/password
timestamp > sysdate -7
group by username,os_username,userhost, client_id,trunc(timestamp);
注释:自 10G 起,USERHOST 列仅填充客户端主机名称,在早期版本中,这是用户在 RAC 环境中访问数据库的 Oracle 实例的数字实例 ID。
您可以选择选择更多列,但是这些列可能不会为您提供相关信息,您检查此注释的原因可能是您在此处找到了一些条目并需要更多信息。尝试将 DBA_USERS.LOCK_DATE 与正在运行的脚本或批处理作业的时间关联起来。
"init.ora" 参数文件中设置 Event
在参数文件中设置以下事件,以便在生成 ORA-1017 时 dump trace 文件:
event = "1017 trace name errorstack level 10"
或者,您可以以特权用户身份执行以下命令,这只会影响新进程,因此可能无法在共有连接环境生效:
alter system set events '1017 trace name errorstack level 10';
每当有人尝试输入无效的用户名/密码时,这都会在 user_dump_dest 中生成一个 trace 文件,因为 trace 是在 Level 10 上请求的,所以它将包含一个标记为 PROCESS STATE 的部分,例如:
O/S info: user: userx, term: pts/1, ospid: ***** , machine: *****
program: sqlplus@***** (TNS V1-V3)
application name: sqlplus@**** (TNS V1-V3), hash value=0
last wait for 'SQL*Net message from client' blocking sess=0x0 seq=2 wait_tim
e=5570 seconds since wait started=0
在本例中,是由操作系统用户“userx”启动的 sqlplus 客户端启动了客户端会话。 Call Stack Trace 部分可能会帮助支持进一步诊断问题。 提示:如果操作系统用户或程序是“oracle”,则连接可能源自数据库连接。
使用触发器捕获附加信息
以下触发器代码可用于收集有关不成功登录尝试的其他信息,如果您已经有此触发事件的触发器而不是在同一事件上有更多触发器,建议将此代码集成到现有触发器中,请注意,这只是一个提供一些基本信息的示例,可以随意更改或修改,例如您可能更喜欢将条目记录在表中而不是alert.log文件中,即使会话未经过身份验证,该触发器也会触发,请保持触发代码尽可能简单,以尽量减少对性能的影响。
-- sample trigger to write diagnostic info to alert.log
-- for failed login attempts (ora-1017)
create or replace trigger logon_denied_to_alert
after servererror on database
declare
message varchar2(256);
IP varchar2(15);
v_os_user varchar2(80);
v_module varchar2(50);
v_action varchar2(50);
v_pid varchar2(10);
v_sid number;
v_program varchar2(48);
v_client_id VARCHAR2(64);
begin
IF (ora_is_servererror(1017)) THEN
-- get IP for remote connections:
if sys_context('userenv','network_protocol') = 'TCP' then
IP := sys_context('userenv','ip_address');
end if;
select distinct sid into v_sid from sys.v_$mystat;
SELECT p.SPID, v.PROGRAM into v_pid, v_program
FROM V$PROCESS p, V$SESSION v
WHERE p.ADDR = v.PADDR AND v.sid = v_sid;
v_os_user := sys_context('userenv','os_user');
dbms_application_info.READ_MODULE(v_module,v_action);
v_client_id := sys_context('userenv','client_identifier');
message:= to_char(sysdate,'Dy Mon dd HH24:MI:SS YYYY')||
' logon denied '|| 'IP ='||nvl(IP,'localhost')||' pid = '||v_pid||
' os user = '||v_os_user||' client id = '||v_client_id||
' with program= '||v_program||' module ='||v_module||' action='||v_action;
sys.dbms_system.ksdwrt(2,message);
-- remove comments from next line to let it hang for 5 minutes
-- to be able to do more diagnostics on the operating system:
-- sys.dbms_lock.sleep(300);
end if;
end;
/
-- end trigger
Alert.log 的一些示例输出如下所示:
Fri May 20 10:00:50 2011 Fri May 20 10:00:50 2011 logon denied IP = localhost pid = **** os user = oracle client id = with program= sqlplus@<host name> (TNS V1-V3) module=sqlplus@<host name> (TNS V1-V3) action=
更多属性可以在 note 120797.1 中找到,但是请考虑当此触发器因登录尝试不成功而触发时,并非所有会话特定信息都可用,就像对于经过身份验证的会话一样。
使用 SQLNET 跟踪收集详细信息
sqlnet trace 可以为您提供有关连接尝试的更多详细信息,仅当上述内容没有为您提供足够的信息时才使用此 trace,因为如果启用 sqlnet trace,将很难找到您要查找的内容,创建或编辑服务器端 sqlnet.ora 文件并输入以下参数来启动 sqlnet trace:
# server side sqlnet trace parameters
trace_level_server = 16
trace_file_server=server
trace_directory_server = <any directory on a volume with enough freespace>
作为最后的手段,您可能希望将希望寄托在网络或操作系统级别的数据包嗅探器上,但是此类工具的使用超出了本文的范围,您可能需要咨询本地网络管理员了解这种可能性。
注意:如果您看到您的 RDBMS 帐户被锁定(ORA-28000 "The account is locked." 报错),即使用户从未连续多次提供错误密码 FAILED_LOGIN_ATTEMPTS,并且审计中没有 ORA-1017 报错,则可能是一个已知错误导致此问题,并且必须应用补丁来修复问题 Bug 30210753。
请应用补丁并验证问题是否得到解决。
(应用补丁来修复问题 Bug 30210753(包含在 19.10 及更高版本的 RU 中))




