Oracle如何找到导致账户锁定的IP的一些思考和总结。转载本文请联系DBA杂念公众号。在ORACLE数据库中,如果没有修改FAILED_LOGIN_ATTEMPTS,用户默认输错密码10次后会被锁定。SQL>SELECT*2FROMDBA_PROFILES3WHERERESOURCE_NAME='FAILED_LOGIN_ATTEMPTS';PROFILERESOURCE_NAMERESOURCELIMIT--------------------------------------------------------------------------------------------------------------DEFAULTFAILED_LOGIN_ATTEMPTSPASSWORD10MONITORING_PROFILEFAILED_LOGIN_ATTEMPTSPASSWORDUNLIMITEDSQL>那么在数据库维护过程中,如果账号被锁了,之后??如何分析是哪个IP或者host导致的现在被锁定?不同的情况有不同的分析方法,主要看是否开启数据库审计功能。如果开启了审计功能,分析定位就非常简单容易了。因为数据库的审计功能会将这些信息记录到数据库中。检查审计是否开启,主要检查audit_sys_operations参数是否为TRUE。SQL>showparameterauditNAMETYPEVALUE---------------------------------------------------------------------------audit_file_deststring/u01/app/oracle/admin/gsp/adumpaudit_sys_operationsbooleanTRUEaudit_syslog_levelstringaudit_trailstringDB_EXTENDEDSQL>如果审计功能开启后,通过下面的SQL语句,可以很方便的找到造成账号锁定的主机(通过主机找到具体的IP地址)----RETURNCODE=1017表示登录失败,返回ORA-01017:invalid用户名密码;登录被拒绝错误的会话信息。选择USERNAME、USERHOST、TIMESTAMP、RETURNCODEFROMdba_audit_sessionWHEREUSERNAME='TEST'ANDRETURNCODE='1017'ORDERBYTIMESTAMPDESC;databaseauditoff如果关闭了数据库审计功能,你能定位并找到导致账户被锁定的主机或IP地址吗?如果有账户被锁定的情况,可以先查看dba_users视图,看看账户是什么时候被锁定的。注意(部分版本有bug,LOCK_DATE会不准确。)SQL>ALTERSESSIONSETNLS_DATE_FORMAT='YYYY-MM-DDHH24:MI:SS';Sessionaltered.SQL>SELECTusername,account_status,lock_date,PROFILE2FROMdba_usersWHEREusername='TEST';USERNAMEACCOUNT_STATUSLOCK_DATEPROFILE----------------------------------------------------------------------------------------TESTLOCKED(TIMED)2018-06-1623:49:14DEFAULTSQL>网上有些文章发誓可以通过监控日志分析我找到了是哪些IP导致了账号被锁,但是经过动手实验分析发现通过监控日志文件无法定位到导致账号被锁的IP地址。原因有二:1、无法通过监控日志判断登录会话是否存在ORA-01017错误,因为登录成功和登录失败的会话监听日志信息是一样的。无法区分!2.即使可以秒级定位账号锁定时间,但在生产环境中,一秒内产生大量监控日志,无法定位到具体的IP3。登录失败的监控日志可能不连续。相反,它是在一段时间内产生的。但是,如果事先定义好数据库触发器,就可以很容易地定位到具体的IP。有网友提供了一个触发器,如下图:);v_actionVARCHAR2(50);v_pidVARCHAR2(10);v_sidNUMBER;v_programVARCHAR2(48);v_usernameVARCHAR2(32);BEGINIF(ora_is_servererror(1017))THEN--getipFORremoteconnections:IFupper(sys_context('userenv','network)_protocol'TCP'THENip:=sys_context('userenv','ip_address');ENDIF;SELECTsidINTOv_sidFROMsys.v_$mystatWHERErownum<2;SELECTp.spid,v.programINTOv_pid,v_programFROMv$processp,v$sessionvWHEREp.addr=v.paddrANDv.sid=v_sid;v_os_user:=sys_context('userenv','os_user');v_username:=sys_context('userenv','authenticated_identity');dbms_application_info.read_module(v_module,v_action);消息:=to_char(SYSDATE,'YYYY-MM-DDHH24:MI:SS')||'PasswordErro:logondeniedfrom'||nvl(ip,'localhost')||''||v_pid||'用户:'||v_os_user||'with'||v_program||'–'||v_module||''||v_action||'dbuser:'||v_username;sys.dbms_system.ksdwrt(2,message);ENDIF;END;/在客户端使用SQL*Plus测试模拟输入错误密码登录数据库C:\Users>sqlplustest/1234@myvmSQL*Plus:Release11.2.0.1.0ProductiononSundayJun1700:35:212018Copyright(c)1982,2010,Oracle.Allrightsreserved.ERROR:ORA-01017:invalidusername/password;logondenied此时触发捕获当出现该错误时,报警日志中会产生类似如下的错误日志信息:SunJun1708:01:4420182018-06-1708:01:44PasswordErro:logondeniedfrom192.168.125.19326639User:KongLBwithsqlplus.exe...sqlplus.exedbuser:test当然,如果你也可以重写触发器,将捕获到的相关信息写入数据库的相关表中。目前我将登录失败信息写入报警日志,监控报警日志的作业(alert_$ORACLE_SID.log)会写入分析报警日志,定期分析错误,发给DBA!
