Oracle数据库审计
数据库审计是监视并记录选定的用户数据库操作。主要分为标准审计和精细粒度审计(FGA,Fine-Grained Auditing),标准审计可在语句级、对象级、权限级进行审计;精细粒度审计涉及到基于内容或特定数据的审计。
启用审计:
1、启用审计需要修改audit_trail的值,默认为NONE.
SQL> show parameter audit;
NAME                   TYPE        VALUE
---------------------- ----------- ------------------------------
audit_file_dest        string      /opt/oracle/product/10.0/admin/hunt/adump
audit_sys_operations   boolean     FALSE
audit_syslog_level     string     
audit_trail            string      NONE

audit_trail的取值可有以下几种:
SELECT * FROM V$parameter_Valid_Values where name='audit_trail';
    NUM NAME ORDINAL VALUE ISDEFAULT 备注
1 911 audit_trail 1 DB FALSE 
2 911 audit_trail 2 OS FALSE 
3 911 audit_trail 3 NONE FALSE 默认
4 911 audit_trail 4 TRUE FALSE 与DB一致
5 911 audit_trail 5 FALSE FALSE 与NONE一致
6 911 audit_trail 6 DB_EXTENDED FALSE 
7 911 audit_trail 7 XML FALSE 
8 911 audit_trail 8 EXTENDED FALSE XML_EXTENDED

 NONE:禁用数据库审计。NONE为此参数的默认值。
 OS:指出Oracle将把审计记录写到一个操作系统文件中。
 DB:指出Oracle将把审计记录写入数据库审计跟踪,可视为DBA_AUDIT_TRAIL(存储在SYS.AUD$表中)。
 DB_EXTENDED:指出Oracle将把所有审计记录发送到数据库审计跟踪,除此之外,填充SQLBIND和SQLTEXTCLOB列。
 XML:指定数据库审计,进入OS文件的是XML格式的审计记录。
 XML_EXTENDED:与XML设置相同,另外还记录所有审计跟踪列,包括SQLTEXT和SQLBIND。
如果指定AUDIT_TRAIL=OS,则审计跟踪不再数据库中存储审计信息,而是在由AUDIT_TRAIL_DEST参数指定的位置存储审计信息。如果指定AUDIT_TRAIL=OS且省略AUDIT_TRAIL_DEST参数,则默认将审计信息写到$ORACLE_HOME/rdbms/audit/目录中。
2、修改audit_trail:
SQL>alter system set audit_trail=db_extended scope=spfile;
重启数据库
SQL> show parameter audit;

NAME                   TYPE        VALUE
---------------------- ----------- ------------------------------
audit_file_dest        string      E:\ORACLE\PRODUCT\10.2.0\ADMIN
                                   \HUNT\ADUMP
audit_sys_operations   boolean     FALSE
audit_trail            string      DB_EXTENDED   ----已改变

标准审计:
1、 权限审计:
基于系统的权限进行的审计,如create session、select{insert|update} any table ……,具体的权限可查询system_privilege_map。

A、 开启create session 审计:
SQL> show user;
USER 为 "SYS"
SQL> audit create session ;
审计已成功。
            查询表dba_priv_audit_opts可看到如下结果:  
    USER_NAME PROXY_NAME PRIVILEGE SUCCESS FAILURE
1   CREATE SESSION BY ACCESS BY ACCESS
            使用其他用户登录系统,查看dba_audit_trail可获得对登录用户的审计结果:
    OS_USERNAME USERNAME USERHOST TERMINAL TIMESTAMP OWNER ……
1 hunt\Administrator ADMIN WORKGROUP\hunt hunt 41026.8511    ……

B、 指定审计用户:
SQL> show user;
USER 为 "SYS"
SQL> audit create any table by test;
审计已成功。
            查询表dba_priv_audit_opts可看到如下结果:  
    USER_NAME PROXY_NAME PRIVILEGE SUCCESS FAILURE
1     CREATE SESSION BY ACCESS BY ACCESS
2 TEST   CREATE ANY TABLE BY ACCESS BY ACCESS
此时只有test 进行create table 才进行审记。
C、 指定审计范围:
默认对成功或失败的审计操作进行记录,实际的应用中我们往往更多的在意那些不成功的情况,比如系统登录。
SQL> show user;
USER 为 "SYS"
SQL> audit delete any table whenever not successful;
审计已成功。

whenever [not] successful:
whenever successful 操作成功(dba_audit_trail中returncode字段为0) 才审计,
whenever not successful 反之。省略该子句的话,不管操作成功与否都会审计。
            查询表dba_priv_audit_opts可看到如下结果: 

    USER_NAME PROXY_NAME PRIVILEGE SUCCESS FAILURE
1     CREATE SESSION BY ACCESS BY ACCESS
2     DELETE ANY TABLE NOT SET BY SESSION
3 TEST   CREATE ANY TABLE BY ACCESS BY ACCESS

取消审计只需要将审计语句中的audit改为noaudit即可:
noaudit create any table by test;
no audit create session;
2、 对象审计:
按对象审计,只审计on关键字指定对象的相关操作。
A、 开启审计:
SQL> show user;
USER 为 "ADMIN"
SQL> audit select on t;
审计已成功。
查询表dba_obj_audit_opts可看到如下结果:
    OWNER OBJECT_NAME OBJECT_TYPE …… SEL UPD REF EXE CRE REA WRI FBK
1 ADMIN T TABLE …… S/S -/- -/- -/- -/- -/- -/- -/-
       表中的SEL代表select ,对应的S/S指:SESSION级成功审计/失败审计。此处S可能为SESSION也可能为ACCESS.区别在于:
by access 每一个被审计的操作都会生成一条audit trail。
by session 一个会话里面同类型的操作只会生成一条audit trail,默认为by session。

    查询T表,dba_audit_trail中记录的部分审计结果如下:
    OS_USERNAME USERNAME OWNER OBJ_NAME SES_ACTIONS SQL_TEXT
1 hunt\Administrator ADMIN ADMIN T ---------S------ select * from t
---------S------ 与上一表格中的内容对应S代表SEL的审计权限。
B、 打开全部审计权限:
SQL> show user;
USER 为 "ADMIN"
SQL> audit all on t;
审计已成功。
查询表dba_obj_audit_opts可看到如下结果:
    OWNER OBJECT_NAME OBJECT_TYPE ALT AUD COM DEL GRA IND INS LOC …
1 ADMIN T TABLE S/S S/S S/S S/S S/S S/S S/S S/S …

SQL> Audit all on t by access;
    OWNER OBJECT_NAME OBJECT_TYPE ALT AUD COM DEL GRA IND INS LOC …
1 ADMIN T TABLE A/A A/A A/A A/A A/A A/A A/A A/A …

3、 语句审计:
按语句来审计,比如audit table 会审计数据库中所有的create table,drop table,truncate table语句。
A、 开启审计:
SQL> show user;
USER 为 "ADMIN"
SQL> audit table by test;
审计已成功。
查询表dba_stmt_audit_opts可看到如下结果:
    USER_NAME PROXY_NAME AUDIT_OPTION SUCCESS FAILURE
1     CREATE SESSION BY ACCESS BY ACCESS
2     DELETE ANY TABLE NOT SET BY SESSION
3 TEST   CREATE ANY TABLE BY ACCESS BY ACCESS
4 TEST   TABLE BY ACCESS BY ACCESS
语句审计与权限审计有交叉。
此时我们用test用户创建一个表,查看dba_audit_trail中记录的部分审计结果如下:
    USERNAME OWNER OBJ_NAME ACTION_NAME SQL_TEXT
8 TEST TEST TAB_T CREATE TABLE create table tab_t(id int,name char(10))

通过长时间的审计,dba_audit_trail表会不断的增长,可以通过清空aud$ 达到删除审计的目的。

SYS用户登录时数据库会启用强制审计,WINDOWNS里的事件查看器里,内容如下:
事件类型: 信息
事件来源: Oracle.hunt
事件种类: 无
事件 ID: 34
日期:  2012-4-27
事件:  20:22:24
用户:  N/A
计算机: WWW-61131B590F7
描述:
Audit trail: ACTION : 'CONNECT' DATABASE USER: 'sys' PRIVILEGE : SYSDBA CLIENT USER: hunt CLIENT TERMINAL: LENOVO-PC STATUS: 0 .
LINXU下位于$ORACLE_HOME/admin/$ORACLE_SID/adump下,内容如下:
     Audit file /opt/oracle/product/10.0/admin/wlan/adump/ora_18094.aud
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
ORACLE_HOME = /opt/oracle/product/10.0
System name:    SunOS
Node name:      crmdb
Release:        5.10
Version:        Generic_141414-07
Machine:        sun4v
Instance name: wlan
Redo thread mounted by this instance: 1
Oracle process number: 53
Unix process pid: 18094, p_w_picpath: oracle@wlandb (TNS V1-V3)

Fri Apr 27 12:10:01 2012
ACTION : 'CONNECT'
DATABASE USER: '/'
PRIVILEGE : SYSDBA
CLIENT USER: oracle
CLIENT TERMINAL:
STATUS: 0

精细粒度审计:
A、 定义审计策略:
begin
  dbms_fga.add_policy(object_schema   => 'ADMIN',
                      object_name     => 'T',
                      policy_name     => 'audit_t',
                      audit_column    => 'SALARY',
                      enable          => TRUE,
                      statement_types => 'select,insert,update,delete');

end;
/
查询dba_audit_policies 表,结果如下;

    OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_COLUMN SEL INS UPD DEL
2 ADMIN T AUDIT_T SALARY YES YES YES YES

此时我们对T表进的SALARY列进行操作,然后查询dba_fga_audit_trail表,部分审计结果如下:
    OBJECT_SCHEMA OBJECT_NAME POLICY_NAME SQL_TEXT STATEMENT_TYPE
1 ADMIN T AUDIT_T select * from t SELECT
2 ADMIN T AUDIT_T update t set salary=1000 where id=1 UPDATE
3 ADMIN T AUDIT_T insert into t values(3,'c',2000) INSERT

删除策略:

begin
  dbms_fga.drop_policy(object_schema => 'ADMIN',
                       object_name   => 'T',
                       policy_name   => 'AUDIT_T');
end;
精细粒度的审计日志可以通过删除sys.fga_log$表进行清空。

最后,审计日志的清理:
1、 直接清除sys.aud$和sys.fga_log$表;
2、 利用DBMS_AUDIT_MGMT.INIT_CLEANUP设置策略清除:
BEGIN
 IF
   NOT DBMS_AUDIT_MGMT.IS_CLEANUP_INITIALIZED(DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD)
 THEN
   DBMS_AUDIT_MGMT.INIT_CLEANUP(
      audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
      default_cleanup_interval => 12 /* hours */);
 END IF;
END;
/
包的具体用法可参考:
http://docs.oracle.com/cd/E11062_01/admin.1023/e11059/avadm_app_d_audit_mgmt.htm
3、转移表空间(未测试)
alter table sys.aud$ move tablespace users;
alter table sys.aud$ move lob(sqlbind) store as( tablespace USERS);
alter table sys.aud$ move lob(SQLTEXT) store as( tablespace USERS);
alter index sys.I_AUD1 rebuild tablespace users;