如何看數據庫的用戶登錄的記錄檔案
1 audit
用審記來記錄用戶的操作信息
2 trigger
用系統觸發器來記錄用戶登錄
3 logmnr
從log文件中挖出用戶登錄信息
推薦使用第3種,不占用系統資源,而且很方便。
===============================
Oracle 中記錄用戶登錄信息
我們可以使用 Oracle Audit 函數來記錄用戶登錄信息,但是如果開放了 Audit 函數將會使Oracle 性能下降,甚至導致 Oracle 崩潰。那我們如何才能記錄用戶登錄信息呢?其實我們可以通過建立觸發器的方式來實現。方法如下:
1. 用 sys 用戶登錄 Oracle
2. 創建記錄用戶登錄信息的表
CREATE TABLE LOG$INFORMATION
(
ID NUMBER(10),
USERNAME VARCHAR2(30),
LOGINTIME DATE,
TERMINAL VARCHAR2(50),
IPADRESS VARCHAR2(20),
OSUSER VARCHAR2(30),
MACHINE VARCHAR2(64),
PROGRAM VARCHAR2(64),
SID NUMBER,
SERIAL# NUMBER,
AUSID NUMBER
)
/
3. 創建一個 Sequence,作為登錄信息的主鍵
CREATE SEQUENCE LOGIN_SEQ
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
cache 20
/
4. 創建觸發器,記錄用戶登錄信息
CREATE OR REPLACE TRIGGER LOGIN_RECORD_TR
AFTER logon ON DATABASE
DECLARE
mtSession v$session%ROWTYPE;
CURSOR cSession(iiQuerySid IN NUMBER) IS
SELECT * FROM v$session
WHERE audsid = iiQuerySid;
BEGIN
OPEN cSession(userenv('SESSIONID'));
FETCH cSession INTO mtSession;
IF cSession%FOUND AND SYS_CONTEXT ('USERENV','IP_ADDRESS') IS NOT NULL THEN
INSERT INTO log$information(
id,
username,
logintime,
terminal,
ipadress,
osuser,
machine,
program,
sid,
serial#,
ausid
) VALUES(
login_seq.nextval,
USER,
SYSDATE,
mtSession.Terminal,
SYS_CONTEXT ('USERENV','IP_ADDRESS'),
mtSession.Osuser,
mtSession.Machine,
mtSession.Program,
mtSession.Sid,
mtSession.Serial#,
userenv('SESSIONID')
);
END IF;
CLOSE cSession;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
/
5. 將 SYS.LOG$INFORMATION 授權給需要查看登錄記錄的用戶
Grant select on SYS.LOG$INFORMATION to XXX
/
=======================================
審計用戶登錄和登出
記錄每個用戶每次登錄數據庫和退出數據庫的日期和事件。設置步驟如下:
1. 設置系統審計相關的參數
2. 重新啟動數據庫
3.以SYSTEM帳號登錄數據庫執行下列語句,設置CONNECT審計並檢查是否設置成功:
SQL> connect system/password
SQL> audit connect
SQL> col user_name format a11
SQL> col audit_option format a14
SQL> select user_name, audit_option, success, failure
from sys.dba_stmt_audit_opts;
USER_NAME AUDIT_OPTION SUCCESS FAILURE
----------- -------------- ---------- ----------
CREATE SESSION BY ACCESS BY ACCESS
4.查詢 AUD$表就可以查看到審計結果了
SQL> col userid format a8
SQL> select sessionid, to_char(timestamp#,'DD-MON-YY:HH24:MI:SS') login,
userid, to_char(logoff$time,'DD-MON-YY:HH24:MI:SS') logoff
from sys.aud$ where userid='SCOTT';
SESSIONID LOGIN USERID LOGOFF
---------- ------------------ -------- ------------------
132 22-FEB-00:13:55:06 SCOTT 22-FEB-00:14:04:05
注意:不同的版本的ORACLE數據庫AUD$字典會有所不同,實際情況請參照你當前版本的數據庫的AUD$表。
1.4.11 審計SYS用戶的操作(ORACLE 9i Release 2)
在ORACLE 9.2之前,SYS帳戶是系統中的一個唯一不受審計的帳戶。在ORACLE 9I Release 2和以后的版本中,通過一些設置就可以對SYS帳號進行審計。
在ORACLE 9.2以后的版本中,可以通過設置AUDIT_SYS_OPERATIONS可以實現對具有SYS/SYSDBA/SYSOPER權限的用戶的審計。
1.4.12 使用WINDOWS 事件管理器來記錄審計信息
和UNIX系統不同,WINDOWS的審計結果不是存儲在操作系統文件中,而是直接存儲在WINDOWS 事件日志中。本節介紹如何配置數據庫審計,並用事件管理器來查看審計記錄。
在WINDOWS下設置數據庫審計,需要按照如下的步驟:
1、配置審計
首先要確認WINDOWS的事件日志(EVENTLOG)服務是否啟動。可以通過“控制面板/管理工具/服務”工具來查看。
然后通過修改ORACLE的參數(參數修改方法參見前面的關於ORACLE參數文件的描述)AUDIT_TRAIL:
AUDIT_TRAIL=0S
在WINDFOWS平台下要注意的是:
不管AUDIT_TRAIL設置為什么值,有部分ORACLE的操作會記錄在事件日志中
在WINDOWS下不支持AUDIT_FILE_DEST參數,如果設置了該參數,數據庫會報錯
LRM-00101: UNKNOWN PARAMETER NAME 'AUDIT_FILE_DEST'
ORA-01078: FAILURE IN PROCESSING SYSTEM PARAMETERS
在使用審計前,要確保事件日志有足夠大的空間來存儲審計信息
2、檢查是否安裝好AUDIT相關的對象
最簡單的檢查方法是看看AUD$是否存在。如果AUDIT相關對象安裝不正確,可以通過%ORACLE_HOME%\rdbms\admin\cataudit.sql腳本來安裝AUDIT相關對象。如果要刪除審計,可以執行%ORACLE_HOME%\rdbms\admin\catnoaud.sql。
3、配置審計
在配置審計之前,首先要說明的是,審計是一種會帶來額外開銷的操作。因此在可能的情況下,盡量減少審計操作。另外,如果打開審計操作,那么對一些數據庫事件的審計是缺省的,這些審計事件包括:
實例關閉
通過SYSOPER和SYSDBA連接數據庫
在WINDOWS下配置審計的步驟和在UNIX下配置審計類似,這里就不再描述了。審計信息會自動寫入WINDOWS的事件日志種,通過事件管理器可以查看日志。
=====================================
如何使用Logmnr方法分析數據庫日志
本文用舉例的形式來講解使用Logmnr方法分析數據庫日志。
一、安裝LogMiner工具
(以下兩個腳本以SYSDBA身份運行)
@$ORACLE_HOME\rdbms\admin\dbmslm.sql;
@ $ORACLE_HOME\rdbms\admin\dbmslmd.sql;
第一個腳本用來創建DBMS_LOGMNR包,該包用來分析日志文件。
第二個腳本用來創建DBMS_LOGMNR_D包,該包用來創建數據字典文件。
二、使用LogMiner工具
下面將詳細介紹如何使用LogMiner工具。
1、創建數據字典文件(data-dictionary)
(1)首先在init.ora初始化參數文件中,指定數據字典文件的位置,也就是添加一個參數UTL_FILE_DIR,該參數值為服務器中放置數據字典文件的目錄。
如:UTL_FILE_DIR = ($ORACLE_HOME\logs) ,重新啟動數據庫,使新加的參數生效。
(2)創建數據字典文件:
SQL> connect /as sysdba
SQL> execute dbms_logmnr_d.build(dictionary_filename =>
'dict.ora',dictionary_location => 'G:\oracle\logs');
PL/SQL procedure successfully completed
2、創建要分析的日志文件列表:
(1)創建分析列表,即所要分析的日志:
SQL> execute dbms_logmnr.add_logfile(LogFileName =>
'G:\ORACLE\ORADATA\ORADBSP\REDO04.LOG',Options => dbms_logmnr.new);
PL/SQL procedure successfully completeds
(2)添加分析日志文件(一次添加1個為宜):
SQL>
execute dbms_logmnr.add_logfile(LogFileName =>
'G:\ORACLE\ORADATA\ORADBSP\REDO05.LOG',
Options => dbms_logmnr.ADDFILE);
PL/SQL procedure successfully completed
3、使用logMiner進行日志分析:
(1)無限制條件,即用數據字典文件對要分析的日志文件所有內容做分析:
SQL> execute dbms_logmnr.start_logmnr
(DictFileName => 'G:\oracle\logs\dict.ora');
PL/SQL procedure successfully completed
(2)帶限制條件:
可以用scn號或時間做限制條件,也可組合使用--分析日志列表中時間從07.02.28從10:00到15:00的內容。
SQL> execute dbms_logmnr.start_logmnr
(startTime => to_date('20070228100000','yyyy-mm-dd hh24:mi:ss'),
endTime => to_date('20070228150000','yyyy-mm-dd hh24:mi:ss'),
DictFileName => 'G:\oracle\logs\dict.ora');
PL/SQL procedure successfully completed
dbms_logmnr.start_logmnr函數的原型為:
PROCEDURE start_logmnr(
startScn INNUMBER default 0 ,
endScnINNUMBER default 0,
startTimeINDATE default '',
endTime INDATE default '',
DictFileNameINVARCHAR2 default '',
Options INBINARY_INTEGER default 0 );
4、分析后釋放內存:
SQL> execute dbms_logmnr.end_logmnr;
PL/SQL procedure successfully completed
5、其它:
(1)刪除日志分析文件:
exec dbms_logmnr.add_logfile
('G:\ORACLE\ORADATA\ORADBSP\REDO04.LOG',
dbms_logmnr.removefile);
三、查看LogMiner工具分析結果
SQL> select * from dict t where t.table_name like '%LOGMNR%';
--看所有與logmnr相關的視圖
TABLE_NAME COMMENTS
------------------------------ ---------------------------
GV$LOGMNR_CALLBACK Synonym for GV_$LOGMNR_CALLBACK
GV$LOGMNR_CONTENTS Synonym for GV_$LOGMNR_CONTENTS
GV$LOGMNR_DICTIONARY Synonym for GV_$LOGMNR_DICTIONARY
GV$LOGMNR_LOGFILESynonym for GV_$LOGMNR_LOGFILE
GV$LOGMNR_LOGSSynonym for GV_$LOGMNR_LOGS
GV$LOGMNR_PARAMETERS Synonym for GV_$LOGMNR_PARAMETERS
GV$LOGMNR_PROCESSSynonym for GV_$LOGMNR_PROCESS
GV$LOGMNR_REGIONSynonym for GV_$LOGMNR_REGION
GV$LOGMNR_SESSIONSynonym for GV_$LOGMNR_SESSION
GV$LOGMNR_STATS Synonym for GV_$LOGMNR_STATS
GV$LOGMNR_TRANSACTIONSynonym for GV_$LOGMNR_TRANSACTION
V$LOGMNR_CALLBACKSynonym for V_$LOGMNR_CALLBACK
V$LOGMNR_CONTENTSSynonym for V_$LOGMNR_CONTENTS
V$LOGMNR_DICTIONARYSynonym for V_$LOGMNR_DICTIONARY
V$LOGMNR_LOGFILESynonym for V_$LOGMNR_LOGFILE
V$LOGMNR_LOGS Synonym for V_$LOGMNR_LOGS
V$LOGMNR_PARAMETERSSynonym for V_$LOGMNR_PARAMETERS
V$LOGMNR_PROCESSSynonym for V_$LOGMNR_PROCESS
V$LOGMNR_REGION Synonym for V_$LOGMNR_REGION
V$LOGMNR_SESSIONSynonym for V_$LOGMNR_SESSION
TABLE_NAME COMMENTS
------------------------------ ------------------------
V$LOGMNR_STATSSynonym for V_$LOGMNR_STATS
V$LOGMNR_TRANSACTION Synonym for V_$LOGMNR_TRANSACTION
GV$LOGMNR_LOGS 是分析日志列表視圖:
分析結果在GV$LOGMNR_CONTENTS 視圖中,可按以下語句查詢:
select scn,timestamp,log_id,seg_owner,seg_type,
table_space,data_blk#,data_obj#,data_objd#,
session#,serial#,username,session_info,
sql_redo,sql_undo from logmnr3 t
where t.sql_redo like 'create%';
如果不能正常查詢GV$LOGMNR_CONTENTS視圖,並報以下錯誤,ORA-01306: 在從 v$logmnr_contents 中選擇之前必須調用 dbms_logmnr.start_logmnr() 。可采用如下方法:
create table logmnr3 as select * from GV$LOGMNR_CONTENTS;
問題解答:
創建數據字典的目 : 讓LogMiner引用涉及到內部數據字典中的部分時為他們實際的名字,而不是系統內部的16進制。數據字典文件是一個文本文件,使用包DBMS_LOGMNR_D來創建。如果我們要分析的數據庫中的表有變化,影響到庫的數據字典也發生變化,這時就需要重新創建該字典文件。另外一種情況是在分析另外一個數據庫文件的重作日志時,也必須要重新生成一遍被分析數據庫的數據字典文件。 在使用LogMiner工具分析redo log文件之前,可以使用DBMS_LOGMNR_D 包將數據字典導出為一個文本文件。該字典文件是可選的,但是如果沒有它,LogMiner解釋出來的語句中關於數據字典中的部分(如表名、列名等)和數值都將是16進制的形式,我們是無法直接理解的。例如,下面的SQL語句:
INSERT INTO dm_dj_swry (rydm, rymc) VALUES (00005, '張三');
LogMiner解釋出來的結果將是下面這個樣子:
insert into Object#308(col#1, col#2)
values (hextoraw('c30rte567e436'),
hextoraw('4a6f686e20446f65'));
DBA需要知道的Oracle 10g的審計內容
【導讀】Oracle 數據庫 10g 審計以一種非常詳細的級別捕獲用戶行為,它可以消除手動的、基於觸發器的審計。假定用戶 Joe 具有更新那張表的權限,並按如下所示的方式更新了表中的一行數據。
Oracle 數據庫 10g 審計以一種非常詳細的級別捕獲用戶行為,它可以消除手動的、基於觸發器的審計。假定用戶 Joe 具有更新那張表的權限,並按如下所示的方式更新了表中的一行數據。
update SCOTT.EMP set salary = 12000
where empno = 123456;
您如何在數據庫中跟蹤這種行為呢?在 Oracle 9i 數據庫及其較低版本中,審計只能捕獲“誰”執行此操作,而不能捕獲執行了“什么”內容。例如,它讓您知道 Joe 更新了 SCOTT 所有的表 EMP,但它不會顯示他更新了該表中員工號為 123456 的薪水列。它不會顯示更改前的薪水列的值—要捕獲如此詳細的更改,您將不得不編寫您自己的觸發器來捕獲更改前的值,或使用 Log Miner 將它們從存檔日志中檢索出來。
這兩種方法都能讓您跟蹤更改的內容並記錄更改前的值,但其成本非常高。使用觸發器編寫審計數據可能會對性能產生主要的影響;鑒於此,在某些情況下(如在第三方應用中)禁止使用用戶定義的觸發器。Log Miner 不會影響性能,但它是依賴於存檔日志的可用性來跟蹤更改的。
細粒度審計 (FGA),是在 Oracle 9i 中引入的,能夠記錄 SCN 號和行級的更改以重建舊的數據,但是它們只能用於 select 語句,而不能用於 DML,如 update、insert 和 delete 語句。因此,對於 Oracle 數據庫 10g 之前的版本,使用觸發器雖然對於以行級跟蹤用戶初始的更改是沒有吸引力的選擇,但它也是唯一可靠的方法。
隨着 Oracle 10g 的到來,由於審計能力的兩個重大的改變,這些限制也隨之而去。由於兩種審計類型涉及到—標准審計(在所有版本中均可用)和細粒度審計(在 Oracle 9i 及其以上版本中可用)—我們將分別對它們進行處理,然后看看它們是如何相互補充以提供一個單一的、強大的跟蹤功能。
新特性
首先,FGA 現在除了支持 select 語句外,還支持 DMA 語句。這些更改都記錄在同一個位置,即表 FGA_LOG$ 中,並通過 DBA_FGA_AUDIT_TRAIL 視圖顯示出來。除了 DML 外,您現在可以選擇只有在訪問了所有或者甚至很少的相關的列后,才可以觸發一個線索。(有關 FGA 在 Oracle 10g 中是如何工作的詳細信息,請參閱該主題的我的技術文章的內容。)
標准審計,是由 SQL 命令 AUDIT 執行的,可用於為特定的對象快速、容易地設置跟蹤。例如,如果您想跟蹤對 Scott 所擁有的表 EMP 的所有更新,您可以發出如下命令:
audit UPDATE on SCOTT.EMP by access;
任何用戶每一次更新表 SCOTT.EMP 時,該命令都會把所有的更新記錄到審計跟蹤表 AUD$ 中,可以通過 DBA_AUDIT_TRAIL 視圖來查看。
這個功能對於 Oracle 10g 之前的版本也是可用的。但是,在那些版本中,寫到跟蹤中的信息僅限於少數相關的項,如:發出該語句的用戶、時間、終端標識號等等;它缺少某些重要的信息,如綁定變量的值。在 Oracle 10g 中,除了以前的版本中所收集到的內容之外,審計操作還捕獲了許多這些重要的信息片斷。用於審計的原始表 AUD$,包含若干個用於記錄它們的新列,相應地,DBA_AUDIT_TRAIL 視圖也包含這些列。讓我們詳細地研究一下。
EXTENDED_TIMESTAMP。 該列以 TIMESTAMP (6) 格式記錄了審計記錄的時間戳,它是用格林尼治標准時間(也稱為全球統一時間)來記錄時間的,其小數點后的秒數到 9 為止,並且帶有時區信息。以這種格式存儲的時間的一個例子如下所示。2004-3-13 18.10.13.123456000 -5:0日期表示為 2004 年 3 月 13 日,是美國的東部標准時間,它比全球統一時間晚 5 小時(用 -5.0 來表示)。這種以擴展格式顯示的時間有助於把審計跟蹤精確定位到一個更窄的時間間隔中,從而增強了它們的用途,特別是在數據庫橫跨多個時區時更是如此。
GLOBAL_UID 和 PROXY_SESSIONID。 當使用某種身份管理組件如 Oracle Internet Directory 進行身份驗證時,用戶對數據庫的訪問權限稍有不同。例如,當將他們訪問數據庫時,可能將他們視為企業用戶。審計這些用戶不會在 DBA_AUDIT_TRAIL 視圖的 USERNAME 列中記錄他們的企業用戶標識號,以使該信息無用。在 Oracle 數據庫 10g 中,全局(或企業)用戶唯一的標識號記錄在 GLOBAL_UID 列中,並且沒有作進一步的處理或設置。該列可用於查詢目錄服務器,以查找有關該企業用戶的完整的詳細信息。
有時企業用戶也許是通過一個代理用戶連接到數據庫,特別是在多層應用中。可以通過命令為用戶提供代理身份驗證:
alter user scott grant connect to appuser;
該命令將允許用戶 SCOTT 以 APPUSER 的身份,作為代理用戶連接到數據庫。在那種情況下,COMMENT_TEXT 列將通過存儲值 PROXY 來記錄事實;但是對於 Oracle 9i 而言,代理用戶的會話標識號將不會進行記錄。在 Oracle 10g 中,PROXY_SESSIONID 列記錄了它,用於精確標識代理會話。
INSTANCE_NUMBER。 在 Oracle 真正應用集群 (RAC) 環境中,它可能有助於知道在進行更改時用戶連接的是哪一個特定的例程。在 Oracle 10g 中,該列記錄了例程號,它是由該例程的初始化參數文件指定的。
OS_PROCESS。 在 Oracle 9i 及其較低的版本中,只會在審計跟蹤中記錄 SID 值;而不會記錄操作系統進程標識號。但是,服務器進程的操作系統進程標識號隨后可能是必要的,例如,用於交叉引用一個線索文件。在 Oracle 10g 中,該值也記錄在該列中。
TRANSACTIONID。 在此就產生了最關鍵的信息價格。假定用戶發出下面的命令:
update CLASS set size = 10 where class_id = 123;
commit;
該命令獲取一個事務項,並且生成一個審計記錄。但是,您怎樣知道該審計記錄真正記錄的是什么內容呢?如果記錄是一個事務,該事務標識號就會存儲在該列中。您可以使用它把審計跟蹤與 FLASHBACK_TRANSACTION_QUERY 視圖聯接起來。下面是該視圖中的列的一個小示例:
select start_scn, start_timestamp,
commit_scn, commit_timestamp, undo_change#, row_id, undo_sql
from flashback_transaction_query
where xid = '<the transaction id>';
除了記錄對該事務所做的通常的統計外,如 undo change#、rowid 等等,Oracle 10g 還可以在 UNDO_SQL 列中記錄撤消對事務所作更改 SQL 命令,以及在 ROW_ID 列顯示的受影響行的 rowid。
系統更改號。 最終,它記錄更改前的值。您怎樣執行該操作呢?按 Oracle 9i 中的 FGA 所指出的那樣,更改前的值可以通過閃回查詢來獲取。但是您需要知道該更改的系統更改號 (SCN),它可以在審計跟蹤的該列中捕獲到。您可以發出下面的命令:
select size from class as of SCN 123456
where where class_id = 123;
這將顯示用戶所看到的內容或更改前的值。
擴展的 DB 審計
記住我們最初的興趣:為了捕獲用戶發出的 SQL 語句,以及在標准審計中無法捕獲的綁定變量。在 Oracle 數據庫 10g 中進入增強型審計,其中這些任務變得如同更改一個簡單的初始化參數一樣微不足道。只需把下列代碼行放入參數文件中。
audit_trail = db_extended
如果使用該參數,該參數將在各列中記錄 SQL 文本和綁定變量值。該值在早期的版本中不可用。
觸發器何時是必要的
避免誤檢。 審計跟蹤是通過來自於原始事務的自治事務生成的。因此,即使原始事務回滾,它們也會提交。
有一個簡單例子演示了這一點。假定我們已在表 CLASS 上為 UPDATE 設置了審計。用戶發出一條語句以將數據值從 20 更新為 10,然后將其回滾,如下所示:
update class set size = 10 where class_id = 123;
rollback
現在該列的 SIZE 值將變成 20,而不是 10,好像用戶從未做過任何事情。但是,即使回滾,審計跟蹤也將捕獲該更改。在某些情況下這可能不是人們所想要的,尤其是用戶執行了許多回滾時。在這種情況下,您也許不得不使用觸發器僅捕獲已提交的更改。如果表 CLASS 上有一個觸發器用於將記錄插入到用戶定義的審計線索中,在回滾的基礎上審計線索也被回滾。
捕獲之前更改的值。 Oracle 提供的審計跟蹤不會顯示更改前后的值。例如,上述的更改將創建一個審計記錄,它顯示了語句和更改的 SCN 號,但沒有顯示更改前的值 (20)。可以使用閃回查詢通過 SCN 號獲取該值,但是它依賴於在撤消段中可用的信息。如果該信息無法在由 undo_retention 時間段指定的期限內捕獲到,就永遠不能檢索出先前的值來。使用觸發器保證了無需依賴於 undo_retention 時間段即可捕獲到該值,並且有時很有用。在這兩種環境下,您可以決定繼續使用觸發器以細粒度的級別來記錄審計跟蹤。
統一的審計跟蹤
由於 FGA 和標准審計捕獲的是相同類型的信息,當把它們結合起來使用時可以提供許多重要的信息。Oracle 數據庫 10g 把這些跟蹤合並到一個稱為 DBA_COMMON_AUDIT_TRAIL 的通用跟蹤中,它是 DBA_AUDIT_TRAIL 視圖和 DBA_FGA_AUDIT_TRAIL 視圖的一個 UNION ALL 視圖。但是,在這兩種審計類型之間有一些重大的區別。
結論
在 Oracle 10g 中,審計已經從一個單純的“操作記錄者”成長為一個“事實記錄機制”,它能以一個非常詳細的級別來捕獲用戶的行為,這可以消除您對手動的、基於觸發器的審計的需要。它還結合了標准審計和 FGA 的跟蹤,這使其更易於跟蹤數據庫訪問,而不用考慮它是如何生成的。
==============================================================
設置審計的實例:對試圖嘗試口令的訪問的審計
本節討論的是一個審計的實例,用於記錄嘗試通過野蠻嘗試法破譯ORACLE帳號口令的例子:
1. 修改審計相關參數(參照上一節介紹的方法)
2. 重啟數據庫
3. 設置審計信息
SQL>AUDIT ALL BY ACCESS WHENEVER NOT SUCCESSFUL
4. 查詢AUD$
SQL> select returncode, action#, userid, userhost, terminal,timestamp
from aud$
RETURNCODE ACTION# USERID USERHOST TERMINAL
---------- ---------- -------- -------------------- --------------------
1017 100 SCOTT WPRATA-BR
1017 100 SCOTT WPRATA-BR
1017 100 SCOTT WPRATA-BR
ORA-1017的含義為錯誤的用戶名口令。通過查看AUD$表可以清楚地看到WPRATA-BR嘗試破譯SCOTT的口令。可以通過下面一個存儲過程來分析AUD$表,找出可疑的信息:
create or replace procedure AuditLogin(Since Varchar2,Times PLS_Integer)
is
USER_ID VARCHAR2(20);
cursor c1 is select userid,count(*) from sys.aud$ where returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd')
group by userid;
cursor C2 IS Select userhost, terminal,TO_CHAR(timestamp#,'YYYY-MM-DD:HH24:MI:SS')
from sys.aud$ WHERE returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd') AND USERID=USER_ID;
ct PLS_INTEGER;
V_USERHOST VARCHAR2(40);
V_TERMINAL VARCHAR(40);
V_DATE VARCHAR2(40);
BEGIN
OPEN C1;
dbms_output.enable(1024000);
LOOP
FETCH C1 INTO USER_ID,CT;
EXIT WHEN C1%NOTFOUND;
IF(CT>=TIMES) THEN
DBMS_OUTPUT.PUT_LINE('USER BROKEN ALARM:'||USER_ID);
OPEN C2;
LOOP
FETCH C2 INTO V_USERhOST,V_TERMINAL,V_DATE;
DBMS_OUTPUT.PUT_LINE(CHR(9)||'HOST:'||V_USERHOST||',TERM:'||V_TERMINAL||',TIME:'||V_DATE);
EXIT WHEN C2%NOTFOUND;
END LOOP;
close c2;
END IF;
END LOOP;
close c1;
END;
/
一下是執行結果:
SQL>set serveroutput on;
SQL> execute auditlogin('2004-01-01',2);
USER BROKEN ALARM:SYS
HOST:,TERM:XUJI,TIME:2004-09-22:11:08:00
HOST:,TERM:XUJI,TIME:2004-09-22:11:08:01
HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29
HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29
PL/SQL 過程已成功完成。
將審計相關的表移動到其他表空間
由於AUD$表等審計相關的表存放在SYSTEM表空間,因此為了不影響系統的性能,保護SYSTEM表空間,最好把AUD$移動到其他的表空間上。可以使用下面的語句來進行移動:
sql>connect / as sysdba;
sql>alter table aud$ move tablespace <new tablespace>;
sql>alter index I_aud1 rebuild online tablespace <new tablespace>;
SQL> alter table audit$ move tablespace <new tablespace>;
SQL> alter index i_audit rebuild online tablespace <new tablespace>;
SQL> alter table audit_actions move tablespace <new tablespace>;
SQL> alter index i_audit_actions rebuild online tablespace <new tablespace>;