ORACLE 11g 實現審計使用者登入登出的詳細記錄
阿新 • • 發佈:2019-01-28
需求就是需要記錄使用者登陸登出的記錄,包括時間以及連線ip地址以及連線方式等等,這樣有助於跟蹤分析問題,特別是一些人為無意識的dml操作導致資料丟失、資料混亂的問題追蹤,還是非常有效的。
大家知道oracle庫開啟了審計audit後,肯定有辦法查到問題,但是審計比較消耗資源,所以可以通過觸發器之類的來間接實現這個功能。
1、建記錄表
-- Create table createtable UC_LOGON_OFF ( user_id VARCHAR2(30), session_id NUMBER(8), host VARCHAR2(30), last_program VARCHAR2(48), last_action VARCHAR2(32), last_module VARCHAR2(32), logon_day DATE, logon_time VARCHAR2(10), logoff_day DATE, logoff_time VARCHAR2(10), elapsed_minutes NUMBER(8), sid NUMBER(8), serial NUMBER(8) ) tablespaceUSERS pctfree10 initrans1 maxtrans255;
PS:後續的索引問題,可以根據資料來隨時新增,提高查詢效率。
2、建立登陸觸發器
CREATEORREPLACETRIGGER trig_logon_audit AFTER LOGON ONDATABASE BEGIN INSERTINTO timdba.uc_logon_off selectUSER, SYS_CONTEXT ('USERENV', 'SESSIONID'), SYS_CONTEXT ('USERENV', 'HOST'), NULL, NULL, NULL, SYSDATE, TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'), NULL, NULL, NULL, NULL, nullfrom dual; END;
3,建立登出的觸發器
登出這裡也採用了insert語句,是考慮到因為使用者如果用了update的話,在登陸記錄裡面做update操作,如果登陸使用者惡意的話,它是可以修改記錄的。它下次登陸後,直接修改上次登陸的記錄的ip地址等等資訊,這樣就會給我們誤導了,當然我們也可以根據歸檔日誌來分析,但是會比較麻煩一些,那麼同理這張記錄表uc_logon_off表就失去記錄的功效了,因為每次我們都會懷疑這裡的記錄是否被認為修過過了,而不是真實的原始記錄。
那現在改成了insert,再加上後面禁止delete、update操作,那麼就確保uc_logon_off表的資料的真實性,雖然有可能被人惡意insert新記錄的可能,但是每次它連線後最後一條記錄都是真實的,這樣我們就只根據uc_logon_off表進行分析就可以得出使用者的操作行為記錄。
CREATE OR REPLACE TRIGGER trig_logoff_audit
BEFORE LOGOFF
ON DATABASE
DECLARE
v_date date;
BEGIN
SELECt t.logon_day INTO v_date from (select logon_day FROM timdba.uc_logon_off where session_id= SYS_CONTEXT ('USERENV', 'SESSIONID') AND logon_day IS NOT NULL order by logon_day asc) t where rownum<2;
INSERT INTO timdba.uc_logon_off
select USER,
SYS_CONTEXT ('userenv', 'SESSIONID'),
SYS_CONTEXT ('userenv', 'host'),
(SELECT action FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
(SELECT program FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
(SELECT module FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
v_date,
TO_CHAR(v_date, 'hh24:mi:ss'),
sysdate,
TO_CHAR(sysdate, 'hh24:mi:ss'),
TRUNC(TO_NUMBER(sysdate - v_date) * 1440,2),
ROUND(TO_NUMBER(sysdate - v_date) * 24 * 60*60 ),
NULL,
SYS_CONTEXT ('userenv', 'ip_address') from dual;
commit;
/*
UPDATE timdba.uc_logon_off
SET last_action = 'v_tag logoff: '||(SELECT action FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
last_program = (SELECT program FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
last_module = (SELECT module FROM v$session WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = audsid),
logoff_day = SYSDATE,
logoff_time = TO_CHAR (SYSDATE, 'hh24:mi:ss'),
elapsed_minutes = 'v_tag logoff:'||TRUNC(TO_NUMBER(sysdate - logon_day) * 1440,2),
elapsed_seconds = ROUND(TO_NUMBER(sysdate - logon_day) * 24 * 60*60 )
WHERE SYS_CONTEXT ('USERENV', 'SESSIONID') = session_id;
*/
COMMIT;
END;
4,禁止刪改登陸登出操作記錄
create or replace trigger timdba.trig_uc_logonoff
before update or delete on timdba.uc_logon_off
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF deleting THEN
RAISE_APPLICATION_ERROR(-20001, 'can not delete ');
ELSIF updating then
RAISE_APPLICATION_ERROR(-20001, 'can not update ');
END IF;
END;
5,給所有的使用者授權記錄操作
因為觸發器裡面需要查詢v$sql以及v$session,還要對timdba.uc_logon_off表進行操作,所以需要賦予這些操作許可權,那麼如果要記錄所有使用者的,就需要把所有使用者都賦予這樣的操作許可權。
--(1) 統計需要授權的語句
grant create session,connect to dw;
grant select on v_$sql to dw;
grant select on v_$session to dw;
grant select,insert on timdba.uc_logon_off to dw;
--(2)建立臨時表,記錄所有使用者
create table timdba.Z_USERS as select distinct owner from all_objects;
--(3)生成授權的sql語句
select 'grant create session,connect to ' || owner ||'; ' from timdba.Z_USERS t where t.owner not in('TIMDBA','SYS','SYSTEM')
union all
select 'grant select on v_$sql to ' || owner ||'; ' from timdba.Z_USERS t where t.owner not in('TIMDBA','SYS','SYSTEM')
union all
select 'grant select on v_$session to ' || owner ||'; ' from timdba.Z_USERS t where t.owner not in('TIMDBA','SYS','SYSTEM')
union all
select 'grant select,insert on timdba.uc_logon_off to ' || owner ||'; ' from timdba.Z_USERS t where t.owner not in('TIMDBA','SYS','SYSTEM');
--(4)將sql結果記錄copy到一個檔案grant_logonoff.sql,放到/home/oracle目錄,然後sqlplus登陸執行sql檔案授權。
SQL> @/home/oracle/grant_logonoff.sql;
Grant succeeded.
Grant succeeded.
Grant succeeded.
……s
6,檢視部分記錄
查詢sql:
select t.elapsed_minutes,t.elapsed_seconds,t.ip,t.*
from uc_logon_off t where t.user_id in('DW','LOGMINER','YS','TIMDBA','PLCRM') and t.elapsed_minutes is not null order by t.logon_day desc,t.session_id desc;
記錄如下圖所示:
C:\pic\oracle\20170330_01.png