ORACLE 11g 实现审计用户登入登出<登陆退出>的详细记录

 

需求就是需要记录用户登陆登出的记录,包括时间以及连接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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值