ORACLE数据库审计

作者简介

普朝晖,现就职于北京海天起点技术服务股份有限公司,担任数据库技术顾问,获有OCP11g证书,具有多年数据库管理维护经验,服务对象覆盖税务、金融、电力等大型企事业单位。擅长于ORACLE数据库环境搭建及故障诊断,对于OGG搭建及维护也颇有见解。

介绍

前段时间突然接到客户服务需求,说要配数据库审计(Audit),这项技术用得比较少,以前一直也没接触过,于是这几天研读了有关文档,对审计也算有了个大致的了解,在此,分享给和我一样之前也没接触过数据库审计的同学,让大家对审计有个较为全面的认识。

数据库审计

下面将通过几个问题让大家更加容易了解数据库审计的相关概念:

1.什么是数据库审计?

顾名思义,对数据库进行审计就是把用户对数据库的操作记录下来以方便日后审查之用。

为什么要审查呢?审查什么呢?哪些情况下需要审查呢?

某公司发现记录在数据库工资表中的某位员工的工资发生了不正常变动,一下从5k元变成了5w,光改回去还不够解气,一定要找出修改数据的元凶打他20大板,这个时候如果数据库早已启用了数据库审计功能,那么直接便可从记录中查看到修改数据的用户甚至ip,那这样找起凶手来就方便多了。

某公司某业务人员在对数据库进行操作时误删除或修改了某条数据,如果这时数据库已经启用了审计功能,那么我们可以查到该操作被执行的具体时间或scn,如果数据库又配置了闪回,那么我们配合闪回技术来精准的恢复修改之前的数据就要方便得多。

除此之外,数据库管理员也可以通过审计来对数据库表的访问量、某段时间数据库连接数及I/O进行统计。

2.是否有种类划分?

答案是肯定的,审计大致可以分为两种,一种是标准审计,还有一种是细粒度审计。(这里先声明一下两者并不是非此即彼的关系,后者和前者的功能基本是一致的,但后者可以在审计条件上做更加细致的设置,后面介绍细粒度审计时再做详细解释)

标准审计

通过标准审计,我们可以审计sql语句、权限、数据库对象及网络活动。用audit/noaudit语句来进行设置。

细粒度审计

细粒度审计和标准审计其实差不多,就是在审计筛选条件上会更加细致一点,比如可以设置当sql语句where条件中涉及到salary > 3000时,该语句才会被记录下来。而布置和维护则是通过DBMS_FGA包来建立相关策略来实现的。

(其实除了以上两种之外数据库中还有一种强制审计,主要记录数据库的启停及sysdba、sysoper的登录信息,不管你有没有开启审计功能,数据库都会将这些记录写在adump目录的dump文件中。而标准审计中又有一些默认审计项,也就是说只要开启审计,例如创建会话、某些权限的使用、某些语句的执行就会被记录下来,当然如果这些信息你并不需要,你也可以手动取消这些默认审计项)

3.记录的信息是如何保存的?

审计的条目既可以保存在数据库表中,也可以保存在操作系统文件中,标准审计通过audit_trail参数来指定存储位置及方式:

DB 保存在数据库中。

DB,EXTENDED 保存在数据库中,信息更为详细,可记录具体SQL语句及绑定变量等。

OS 保存在操作系统文件中。

XML 以XML格式保存在操作系统中(XML格式文件可通过数据库中视图来查看)。XML,EXTENDED 以XML格式保存在操作系统中,记录更详细信息。

NONE 关闭标准审计。

(一般咱们选DB,EXTENDED或OS即可)

而细粒度审计则不需要指定该参数,直接建立策略即可,存储位置由dbms_fga.add_policy过程中的audit_trail参数来指定。

如果选择保存在数据库中,则标准审计条目会保存在sys.aud$表中,细粒度审计条目会保存在sys.fga_log$表中,当然你也可以查看一些其它的视图如dba_audit_trail、dba_sga_audit_trail等来获取不同的整合信息。

(本文后续配置介绍主要以存储在数据库中为例)

配置数据库审计

配置标准数据库审计:

首先要启动标准审计功能,必须得配置audit_trail参数,它不仅是设置标准审计条目存放地点的,它也是审计的启动开关。

配置标准数据库审计主要是通过audit/unaudit语句来实现的,语法格式如下:

(详细请参照官方文档Database SQL Language Reference)

红框:该块指定是对某个sql语句、某个数据库对象还是某个网络活动进行审计。

黄框:该块可指定被审计的用户,也就是说如果设置了audit_by_clause子句,那只有子句指定的用户在执行红框中的操作时才会被记录下来。而in session current子句则指定了审计当前会话的所有操作,通常配合触发器来使用。

蓝框:该块指定了如果同一条语句在一个会话中执行多次是只记录一次(session)还是每次执行都记录(access)。(默认是access)

绿框:该块指定了被审计语句是执行成功了才被记录下来(successful),还是没有成功才被记录下来(not successful),或者不管有没有执行成功都记录下来(默认)。

例:

记录数据库中每一条对scott模式的emp表进行的delete操作:

Sys: Audit delete on scott.emp by access;

用scott用户执行一条delete语句:

Scott: Delete from emp where empno=7369;

查看相关记录:

Sys:Select a.sessionid,a.userid,a.userhost,a.scn,a.ntimestamp#,b.comment$text from aud$ a join aud$ b on a.sessionid=b.sessionid where b.entryid=1 and a.sqltext like‘%delete%’;

(由于同一session的审计记录中只会在第一条即entryid=1的记录里显示ip信息,而ip地址在捉拿嫌犯的时候是很重要的,所以如要获取ip信息就得查看该session的第一条记录。)

取消审计的语句如下图所示,各模块意义基本一样,不作过多解释,详情见官方文档:

配置细粒度审计:

配置细粒度审计是通过dbms_fga包来实现的,语法格式如下:

DBMS_FGA.ADD_POLICY(

object_schema VARCHAR2, 被审计对象所属模式。

object_name VARCHAR2, 被审计对象名。

policy_name VARCHAR2, 该审计策略名。

audit_condition VARCHAR2, 触发审计的条件(如where empno =10)。

audit_column VARCHAR2, 当哪些列被访问时触发审计。

handler_schema VARCHAR2,

handler_module VARCHAR2,

enable BOOLEAN, 是否立即启用。

statement_types VARCHAR2, 语句类型(select,insert,update,delete,merge)

audit_trail BINARY_INTEGER IN DEFAULT, 审计记录存放地点

audit_column_opts BINARY_INTEGER IN DEFAULT,

如果使用audit_column,指定多个列,则该参数标明是所有被指定列都被访问时触发审计,还是其中某几个列被访问就能触发审计。

);

例:

当scott模式中的emp表的sal列值大于3000的记录被删除时,记录审计信息:

Sys:exec DBMS_FGA.ADD_POLICY(

object_schema => ’SCOTT’,

object_name => ’EMP’,

policy_name => ’AUDIT_TEST’,

audit_condition => ’SARALY > 3000’,

audit_trail => DBMS_FGA.DB

statement_types => ’DELETE’);

用scott用户删除emp表中两条数据:

Scott: delete from emp where sal=5000;

Scott: delete from emp where sal=2450;

查看审计记录:

select dbuid,lsqltext,ntmestamp#,scn from fga_log$;

可以看到只有sal=5000的操作被记录了下来。

删除审计策略则用如下方法:

DBMS_FGA.DROP_POLICY(

object_schema => 'HR',

object_name => 'EMPLOYEES',

policy_name => 'chk_hr_employees');

维护审计记录

你以为配置完成了就ok了吗?不是的,对于一个业务繁忙的数据库,配置审计后生成的记录量是很庞大的,所以后期维护这些记录也很重要。

更改表空间

如果记录存放在数据库表里,那么默认是存在system表空间里的,不管是处于性能还是安全考虑,这显然都不太合适,所以咱们得把它移动一下,Oracle也提供了很方便的dbms包来实现这一操作:

BEGIN

DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(

AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT. AUDIT_TRAIL_DB_STD,

AUDIT_TRAIL_LOCATION_VALUE => 'AUD_AUX');

END;

AUDIT_TRAIL_TYPE:要移动的审计类型,以上脚本选的值是标准审计和细粒 度审计。

AUDIT_TRAIL_LOCATION_VALUE:要移动至的表空间名。

归档记录

当aud$或fga_log$长得太大时,将无法插入新的记录,那么这个时候用户执行被审计的操作就会报错。所以如果想长时间存储这些审计记录,就得将aud$和fga_log进行归档,方法比较简单,创建归档专用表,直接插入即可:

INSERT INTO archive_table SELECT ... FROM SYS.AUD$ ...;

INSERT INTO archive_table SELECT ... FROM SYS.FGA_LOG$ ...;

将审计记录归档后,我们就可以对aud$和fga_log$进行清理了

首先要进行清理初始化,否则无法进行清理:

BEGIN

DBMS_AUDIT_MGMT.INIT_CLEANUP(

AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,

DEFAULT_CLEANUP_INTERVAL => 12 );

END;

/

Audit_trail_type:指定要清理的审计类型。

DEFAULT_CLEANUP_INTERVAL:指定清理周期。(此值并非为实际的清理周期,数据库可以根据这个值判断如何进行清理,但建议最好设得和后面真正的清理周期一致)

进行清理初始化之后,我们就可以通过CREATE_PURGE_JOB过程来对审计记录进行定时清理了:

BEGIN

DBMS_AUDIT_MGMT.CREATE_PURGE_JOB (

AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,

AUDIT_TRAIL_PURGE_INTERVAL => 12,

AUDIT_TRAIL_PURGE_NAME => 'Standard_Audit_Trail_PJ',

USE_LAST_ARCH_TIMESTAMP => FALSE );

END;

当然也可以通过CLEAN_AUDIT_TRAIL过程来进行手动清理:

BEGIN

DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(

AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,

USE_LAST_ARCH_TIMESTAMP => FALSE );

END;

补充

1.SYS用户及以sysdba/sysoper身份登录的用户不在标准及细粒度审计范畴之内,要想审计以上两种用户,需要设置AUDIT_SYS_OPERATIONS参数为true,设置完成后以上两种用户的所有操作都将会被记录下来,另外以上两种用户的审计记录默认并只能被保存在AUDIT_FILE_DEST指定的操作系统文件里。

2.为了方便管理这里再介绍几个相关视图:

DBA_AUDIT_POLICIES 记录了已配置的细粒度审计策略相关信息。

DBA_OBJ_AUDIT_OPTS 记录了标准审计中哪些数据库对象被审计。

DBA_PRIV_AUDIT_OPTS 记录了标准审计中哪些数据库权限被审计。

DBA_STMT_AUDIT_OPTS 记录了标准审计中哪些数据库语句被审计。

DBA_AUDIT_MGMT_CLEANUP_JOBS 记录了已配置的清理审计记录策略相关信息。

DBA_AUDIT_MGMT_CLEAN_EVENTS 记录了审计记录的历史清理相关信息。

原创文章,版权归本文作者所有,如需转载请注明出处

喜欢本文请长按下方的二维码订阅Oracle一体机用户组

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180126G0GOHP00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券