Oracle审计功能
Oracle 的审计功能非常的强大,大致包括5个层次
强制审计、标准数据库审计、基于值的审计、精细化审计、对DBA的审计
一、强制审计
审计始终生效(不需要配置),不依赖于数据库某个具体的初始化参数或某个特殊配置,只要以sysdba选项登录到数据库,就会对此进行记录,记录的信息包括:何时、在那个客户端登录到数据库里等。
数据库关闭时同样进行审计,因此审计信息没有记录在数据库的表里,而是记录在操作系统文件里面,对于linux(unix)来说则由初始化参数audit_file_dest的值决定
show parameter audit_file_dest
默认是: app/oracle/admin/pxdb/adump/*.aud
每次以sysdba登录数据库,都会产生一个aud文件,具体命名方式是ora_进程号.aud,需要我们找到当前sessin的进程号,然后找到对应的aud文件,读取文价内容,看到其中的审计信息。
select spid,pid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
[oracle@DFJK-TEST-26 ~]$ cd app/oracle/admin/pxdb/adump
[oracle@DFJK-TEST-26 adump]$ more pxdb_ora_8431_1.aud

二、标准数据库审计
初始化参数audit_trail的值设置成true,可以启用标准数据库审计功能。静态参数,需要重新启动数据库。

•参数audit_trail的值
1、如果设置为OS,则说明审计信息存放在操作系统文件里面,对于linux或者unix来说,就是存放在audit_file_dest目录下面,对于windows来说,就是存放在事件查看器里面。
2、如果设置为DB或者TRUE,则说明审计信息放在数据库里面,也就是sys用户的aud$表,可以通过视图dba_audit_trail视图来查看。
3、如果设置为XML,则审计信息直接写入XML格式的文件里,该文件位于audit_file_dest参数所指定的路径下,通过v$xml_audit_trail视图查询有关XML文件的信息。
DBA应该定期的对审计信息进行查看和归档,并将归档后的审计信息删除,释放空间。
注:修改完成数据库以后,重新启动数据库生效。
•审计选项(audit option)表示要审计什么,可以从下面的四个方面进行设置。
1、审计范围:以session为单位(by session)、已访问单元为单位(by access)。
by session:如果当前session执行了要审计的SQL命令,则只记录一次审计信息,如果该session下次又执行了相同类型的SQL语句,则不再为此记录审计信息。
by access:每次执行要审计的SQL语句,都会进行记录审计信息
因此by access生成的审计信息比by session生成的审计信息要多。默认是by session。
2、审计类型:指定对执行成功的语句进行审计(whenever successfull),还是对执行失败的语句进行审计(whenever not successful),或者不管成功还是失败都进行审计(不指定任何审计类型),默认模式是同时审计成功和不成功的SQL语句。
3、审计特定的用户:可以指定当某个用户执行了要审计的SQL命令时,才记录审计信息,如果其他用户执行了相同的SQL语句,则不记录审计信息。By hr说明只对用户hr执行的命令才判断是否记录审计信息。
4、审计内容:包括对SQL语句进行审计,对系统权限进行审计,或者对对象权限进行审计。
启用审计以后,必须对审计内容进行设置,也就是必须说明要审计的SQL语句、系统权限、还是对象权限。其他的几个方面都有默认值。
1、审计SQL语句
对某种类型的SQL语句进行审计。如果用户test执行了与表有关的命令(例如create table、drop table、truncate table等),命令只要成功,就会审计。
SQL> conn as sysdbaConnected.SQL> audit table by test;Audit succeeded.SQL> conn u1/u1Connected.SQL> create table test123(id int);Table created.SQL> set linesize 200SQL> col obj_name for a10SQL> col username for a5SQL> conn as sysdbaConnected.USERN TIMESTAMP SES_ACTIONS OBJ_NAME ACTION_NAME----- ------------------- ------------------- ---------- ----------------------------U1 2018-10-23 10:09:14 LOGONU1 2018-10-23 10:09:56 LOGOFFSQL> conn test/testConnected.SQL> create table test123(id int);Table created.SQL> conn as sysdbaConnected.SQL> select username,timestamp,ses_actions,obj_name,action_name from dba_audit_trail;USERN TIMESTAMP SES_ACTIONS OBJ_NAME ACTION_NAME----- ------------------- ------------------- ---------- ----------------------------U1 2018-10-23 10:09:14 LOGONU1 2018-10-23 10:09:56 LOGOFFTEST 2018-10-23 10:12:18 LOGONTEST 2018-10-23 10:12:33 TEST123 CREATE TABLETEST 2018-10-23 10:12:40 LOGOFF
对于审计SQL语句来说,设置by session或by access以及设置whenever successful、whenever not successful的意义不大。



发现有5次错误登陆,通过查询1017代码,发现错误信息是错误的用户名和密码。继续追踪这些错误的信息。
select username,count(*) as fail_cnt from dba_audit_trail where returncode=1017 group by username order by fail_cnt desc;

以用户为单位,统计每个用户登录时返回1017代号的次数。
TEST用户是我们的应用账号。
看一下这些失败登陆的具体时间,是否是集中一个时间段,如果是一个集中的时间段,很可能是攻击。
select to_char(timestamp,'yyyy-mm-dd') fail_time,count(*) fail_cntfrom dba_audit_trailwhere returncode=1017and username='TEST'group by to_char(timestamp,'yyyy-mm-dd');

继续查询哪些客户端试图以TEST登陆
SQL> col userhost for a20SQL> col terminal for a15SQL> col os_username for a15SQL> select userhost,terminal,os_username,count(*) fail_cntfrom dba_audit_trailwhere returncode=1017 and username='TEST'and to_char(timestamp,'yyyy-mm-dd') in ('2018-10-23')group by userhost,terminal,os_username;

2、审计系统权限
表示对用户以某个系统权限执行的命令进行审计,用户执行一些命令的时候,需要用到一些系统权限,如果这个系统权限被审计,那么就会产生一条审计记录。
SQL> audit select any table by test;Audit succeeded.SQL> truncate table aud$;Table truncated.SQL> grant select any table to test;Grant succeeded.

select username,timestamp,ses_actions,obj_name,action_name from dba_audit_trail where username='TEST';



如果TEST没有使用select any table,就是select也不会审计。
3、审计对象权限
对某个特定的对象的访问进行审计,我们通常会对一些比较敏感的表进行审计。例如test用户下面的表(EMP)进行审计。
audit select on test.emp by access;




S表示成功的意思,恰好上面的S位于10,也就是对表的select成功。上面的S不是select的意思。另外一个就是F,S(success)和F(fail)是相对的。
B(both)表示既有成功、也有失败。
如果使用的是by access,那么SES_ACTIONS列为空,具体的操作显示在ACTION_NAME列中。
因此SES_ACTIONS只要是对by session有意义。
我们可以在by access和by session下面分别进行不同的操作,然后查看审计信息
注意:标准审计不会影响系统性能。
三、基于值的审计
---慎用,不建议使用触发器。
在标准审计中,只能记录用户做过什么,但是不能记录变化前后的实际值。基于值的审计则可以通过捕获用户进行操作之前和之后的实际值,从而扩展审计功能,这个功能是通过触发器来是实现的。
因为使用触发器(trigger ),而且是用户自己编写程序,因此对系统的性能影响很大。因此通常局限于对某些列的审计,而且这些列的数值变化也不多。
create table system.audit_emp (os_user varchar2(20),update_time date,ip_address varchar2(20),text varchar2(100));create or replace trigger system.emp_sal_auditafter update of sal on test.empreferencing new as new old as oldfor each rowbeginif :old.sal != :new.sal theninsert into system.audit_empvalues (sys_context('userenv','os_user'),sysdate,sys_context('userenv','ip_address'),:new.empno|| ' sal changed from '||:old.sal || ' to '||:new.sal);end if;end;注:sys_context系统函数,用于取环境变量
update test.emp set sal='1200.00' where empno=7369;update test.emp set sal='1500.00' where empno=7369;SQL> select * from system.audit_emp;OS_USER UPDATE_TIME IP_ADDRESS TEXT-------------------- ------------------- -------------------- ------------------------------------dfjk 2018-10-23 13:37:12 172.16.49.42 7369 sal changed from 800 to 1200dfjk 2018-10-23 13:38:20 172.16.49.42 7369 sal changed from 1200 to 1500
四、精细化审计
(fine-grained auditing)FGA
前面的审计,都只是针对某种操作进行审计。但是如果用户的需求为:只有当用户更新了表的某些数据行的时候才需要审计,更新了其他的数据行则不审计。或者只有用户检索的数据行包含指定的某些列的时候才需要审计,等诸如此类的审计需求。需要使用到精细化审计。
FGA从oracle 9i开始引入,FGA不但对行和列精细化审计,而且还记录触发审计的语句。
通过调用DBMS_FGA包来实现FGA,将需要审计的数据内容作为一个策略,在数据库里面进行定义。审计信息记录在数据字典表fga_log$里面,通过查询视图dba_fga_audit_trail可以获得FGA的审计数据。

如果用户修改了销售部门的员工的信息,也即是deptno是30的员工信息,就需要进行审计。
begindbms_fga.add_policy(object_schema =>'TEST',object_name =>'EMP',policy_name =>'audit_emp1',audit_condition =>'deptno=30',enable =>TRUE,statement_types =>'select,update');end;/启动两个session。SQL> select * from emp where deptno=30;

我们还可以执行一些别的SELECT语句进行测试。
SQL> select * from emp where deptno=10;
没有在策略里边不做审计。


fga审计记录存放在这个视图中:select * from dba_fga_audit_trail
该视图对应的后台基表为:sys.fga_log$。注意,fga审计策略不是存放在sys.aud$表中!!!
禁用fga审计策略begindbms_fga.enable_policy(object_schema =>'TEST',object_name =>'EMP',policy_name =>'audit_emp1',enable =>FALSE);end;/
SELECT语句进行测试,无新记录产生。
SQL> select * from emp where deptno=30;

启用fga审计策略begindbms_fga.enable_policy(object_schema =>'TEST',object_name =>'EMP',policy_name =>'audit_emp1',enable =>TRUE);end;/清空fga审计日志:truncate table sys.fga_log$;

在列级别上定义审计信息。begindbms_fga.add_policy(object_schema =>'TEST',object_name =>'EMP',policy_name =>'audit_emp_sal',audit_column =>'sal',enable =>TRUE,statement_types =>'select');end;/audit_column--列级别审计





五、对DBA的审计
前面介绍的所有审计功能,对用户sys都不生效,sys操作都不会被记录下来。




如果我们希望对sys用户进行审计,则需要定义初始化参数audit_sys_operations,默认是false。参数修改后需要重新启动实例。对sys的审计信息存放在文件里,审计文件所在的目录是audit_file_dest决定
SQL> show parameter audit_sys_operationsNAME TYPE VALUE------------------------------------ ----------- ------------------------------audit_sys_operations boolean FALSEaudit_syslog_level stringSQL> show parameter audit_file_destNAME TYPE VALUE------------------------------------ ----------- ------------------------------audit_file_dest string /app/oracle/admin/pxdb/adump





