转http://blog.csdn.net/javacoffe/archive/2010/05/27/5627298.aspx
一、 审计分类:
Oracle 中审计总体上可分为“标准审计”和“细粒度审计”后者也称为“基于政策的审计”,在 Oracle10G 之后功能得到很大增强。 其中标准审计可分为用户级审计和系统级审计。用户级审计是任何 Oracle 用户可设置的审计,主要是用户针对自己创建的数据库表或视图进行审计,记录所有用户对这些表或视图的一切成功和 ( 或 ) 不成功的访问要求以及各种类型的 SQL 操作。系统级审计只能由 DBA 设置,用以监测成功或失败的登录要求、监测 GRANT 和 REVOKE 操作以及其他数据库级权限下的操作。
二、 标准审计:
2.1 分类:
在 ORACLE 中分别 支持以下三种标准审计类型:
u 语句审计,对某种类型的SQL 语句审计,不指定结构或对象。
u 特权审计,对执行相应动作的系统特权的使用审计。
u 对象审计,对一特殊模式对象上的指定语句的审计。
这三种标准审计类型分别对如下 3 方面进行审计:
u 审计语句的成功执行、不成功执行,或者其两者。
u 对每一用户会话审计语句执行一次或者对语句每次执行审计一次。
u 对全部用户或指定用户的活动的审计。
当数据库的审计功能打开后,在语句执行阶段产生审计记录。审计记录包含有审计的操作、用户执行的操作、操作的日期和时间等信息。审计记录可存在数据字典表(称为审计记录)或操作系统审计记录中。数据库审计记录是在 SYS 模式的 AUD$ 表中。
2.2 设置 ORACLE 标准 审计:
下列步骤可以设置 ORACLE 的标准审计功能:
1. 修改初始化参数文件( init<sid>.ora )
如果使用服务器参数文件使用 alter system set <parameter>=<value> scope=spfile|both ,详情参照 1.1 节中关于参数文件的介绍),设置 AUDIT_TRAIL 参数,并且重启数据库。 AUDIT_TRAIL 的取值如下:
l DB/TRUE :启动审计功能,并且把审计结果存放在数据库的 SYS.AUD$ 表中
l OS :启动审计功能,并把审计结果存放在操作系统的审计信息中
l DB_EXTENDED :具有 DB/TRUE 的功能,另外填写 AUD$ 的 SQLBIND 和 SQLTEXT 字段
l NONE/FALSE :关闭审计功能
2. 设置 AUDIT_TRAIL 参数:
如果设置 AUDIT_TRAIL = OS , 还需要修改参数 AUDIT_FILE_DEST 。
如果操作系统支持设置 AUDIT_TRAIL=OS ,文件会自动存放在 AUDIT_FILE
_DEST 所指定的目录下,并且文件名包含进程的 PID 。
比如:
AUDIT_FILE_DEST = $ORACLE_HOME/rdbms/audit
$ ls -l $ORACLE_HOME/rdbms/audit
-rw-rw---- 1 ora92 dba 881 Mar 17 09:57 ora_13264.aud
$ ps -ef|grep 13264
ora92 13264 13235 0 09:56:43 ? 0:00 oracleV92 (DESCRIPTION=(LOCAL=Y)
SQL> select spid, program, username from v$process;
SPID PROGRAM USERNAME
------ -------------------------------------------- -------------
...
13264 oracle@frhp11 (TNS V1-V3) ora92
3. 确认审计相关的表是否已经安装
SQLPLUS> connect / AS SYSDBA
SQLPLUS> select * from sys.aud$; -- 没有记录返回
SQLPLUS> select * from dba_audit_trail; -- 没有记录返回
如果做上述查询的时候发现表不存在,说明审计相关的表还没有安装,需要安装。
SQLPLUS> connect / as sysdba
SQLPLUS> @$ORACLE_HOME/rdbms/admin/cataudit.sql
审计表安装在 SYSTEM 表空间。所以要确保 SYSTEM 表空间又足够的空间存放审计信息。
4. 关闭并重启数据库
5. 设置所需要的审计信息
下面是一个例子
SQL> connect system/manager
SQL> grant audit system to scott;
SQL> connect scott/tiger
SQL> audit session;
停止审计:
SQL> noaudit session;
通常设置了标准审计后都是通过 Audit 语句开启审计,使用 noaudit 语句收回审计。如下所示:
对修改 SC 表结构或数据的操作进行审计可使用如下语句:
AUDIE ALTER , UPDATE ON SC;
取消对 SC 表的一切审计可使用如下语句:
NOAUDIT ALL ON SC;
2.3 设置审计的实例(对试图尝试口令的访问的审计):
以下是一个审计的实例,用于记录尝试通过野蛮尝试法破译 ORACLE 帐号口令的例子:
1. 修改审计相关参数(参照上面介绍的方法)
2. 重启数据库
3. 设置审计信息
SQL>AUDIT ALL BY ACCESS WHENEVER NOT SUCCESSFUL
4. 查询 AUD$
SQL> select returncode, action#, userid, userhost, terminal,timestamp
from aud$
RETURNCODE ACTION# USERID USERHOST TERMINAL
---------- ---------- -------- -------------------- --------------------
1017 100 SCOTT WPRATA-BR
1017 100 SCOTT WPRATA-BR
1017 100 SCOTT WPRATA-BR
ORA-1017 的含义为错误的用户名口令。通过查看 AUD$ 表可以清楚地看到 WPRATA-BR 尝试破译 SCOTT 的口令。可以通过下面一个存储过程来分析 AUD$ 表,找出可疑的信息:
create or replace procedure AuditLogin(Since Varchar2,Times PLS_Integer)
is
USER_ID VARCHAR2(20);
cursor c1 is select userid,count(*) from sys.aud$ where returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd')
group by userid;
cursor C2 IS Select userhost, terminal,TO_CHAR(timestamp#,'YYYY-MM-DD:HH24:MI:SS')
from sys.aud$ WHERE returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd') AND USERID=USER_ID;
ct PLS_INTEGER;
V_USERHOST VARCHAR2(40);
V_TERMINAL VARCHAR(40);
V_DATE VARCHAR2(40);
BEGIN
OPEN C1;
dbms_output.enable(1024000);
LOOP
FETCH C1 INTO USER_ID,CT;
EXIT WHEN C1%NOTFOUND;
IF(CT>=TIMES) THEN
DBMS_OUTPUT.PUT_LINE('USER BROKEN ALARM:'||USER_ID);
OPEN C2;
LOOP
FETCH C2 INTO V_USERhOST,V_TERMINAL,V_DATE;
DBMS_OUTPUT.PUT_LINE(CHR(9)||'HOST:'||V_USERHOST||',TERM:'||V_TERMINAL||',TIME:'||V_DATE);
EXIT WHEN C2%NOTFOUND;
END LOOP;
close c2;
END IF;
END LOOP;
close c1;
END;
/
一下是执行结果:
SQL>set serveroutput on;
SQL> execute auditlogin('2004-01-01',2);
USER BROKEN ALARM:SYS
HOST:,TERM:XUJI,TIME:2004-09-22:11:08:00
HOST:,TERM:XUJI,TIME:2004-09-22:11:08:01
HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29
HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29
PL/SQL 过程已成功完成。
2.4 将审计相关的表移动到其他表空间:
由于 AUD$ 表等审计相关的表存放在 SYSTEM 表空间,因此为了不影响系统的性能,保护 SYSTEM 表空间,最好把 AUD$ 移动到其他的表空间上。可以使用下面的语句来进行移动:
sql>connect / as sysdba;
sql>alter table aud$ move tablespace <new tablespace>;
sql>alter index I_aud1 rebuild online tablespace <new tablespace>;
SQL> alter table audit$ move tablespace <new tablespace>;
SQL> alter index i_audit rebuild online tablespace <new tablespace>;
SQL> alter table audit_actions move tablespace <new tablespace>;
SQL> alter index i_audit_actions rebuild online tablespace <new tablespace>;
三、 细粒度审计:
细粒度审计 (FGA) (通过 Oracle9i 引入)可以理解为“ 基于政策的审计” 。与标准的审计功能相反,FGA 可用于指定生成审计记录必需的条件:
FGA 政策通过使用“dbms_fga” 程序包以编程方式绑定到对象(表、视图)。类似于用于通过 VPD ("dbms_rls") 进行访问控制的程序包,它允许您创建任何需要的条件,例如:仅当以下条件为真时审计事件:
- 在早上九点到下午六点之间或在星期六和星期日对某个表进行了访问。
- 使用了公司网络外部的某个 IP 地址。
- 选定或更新了特定列。
- 使用了该列的特定值。
这将创建更有意义的审计线索,因为无需记录每一个人对表的每一次访问。从 Oracle 数据库 10g 开始,FGA 支持在一个策略中使用“ 选择” 、“ 插入” 、“ 更新” 和“ 删除” 语句的任意组合。事实上,绑定到表的 FGA 政策简化了审计政策的管理,因为这将只需在数据库中对其更改一次,不用在每个应用程序中一次次进行。此外。无论用户通过何种方式连接至数据库(通过应用程序、Web 接口或通过 SQL*Plus ),其操作都会记录下来。
3.1 使用细粒度审计:
1 、创建测试表 :
create table ACCOUNT
(AACT_NO number not null ,
CUST_ID number not null ,
BALANCE number ( 15 , 2 )
);
2 、添加审计策略:
begin
DBMS_FGA.DROP_POLICY(object_schema => 'TEST',
object_name => 'ACCOUNT',
policy_name => 'ACCOUNT_ACCESS');
end;
这段代码必须由具有执行程序包 dbms_fga 权限的用户来执行。建议应该建立一个专门的用户来专门负责添加审计策略。该过程有许多参数,具体含义如下:
OBJECT_SCHEMA | 对其定义了 FGA 策略的表或视图的所有者 |
OBJECT_NAME | 表或视图的名称 |
POLICY_NAME | 策略的名称,由用户自定义 — 例如,ACCOUNTS_ACCESS |
POLICY_TEXT | 在添加策略时指定的审计条件 — 例如,BALANCE >= 11000 |
POLICY_COLUMN | 审计列 — 例如,BALANCE |
ENABLED | 如果启用则为 YES ,否则为 NO |
PF_SCHEMA | 拥有策略处理器模块的模式(如果存在) |
PF_PACKAGE | 处理器模块的程序包名称(如果存在) |
PF_FUNCTION | 处理器模块的过程名称(如果存在) |
3 、 在定义了策略以后,当用户以通常的方式对表进行查询时,如下所示:
select * from bank.accounts;
审计线索记录此操作。可以使用以下语句查看线索:
select timestamp,
db_user,
os_user,
object_schema,
object_name,
sql_text
from dba_fga_audit_trail;
TIMESTAMP DB_USER OS_USER OBJECT_ OBJECT_N SQL_TEXT
--------- ------- ------- ------- -------- ----------------------
26-MAR-10 TEST ananda TEST ACCOUNT select * from account
注意名为 DBA_FGA_AUDIT_TRAIL 的新视图,它记录细粒度的访问信息。其中显示了审计事件的时间标记、查询者的数据库用户 ID 、操作系统用户 ID 、查询中所使用表的名称和所有者,最后还有确切的查询语句。
3.2 审计列和审计条件:
默认情况下会对被审计对象的所有列开启审计,当任何一列被访问时都会纪录一条审计信息,这在现实情况下不太常见,因为这样会使审计信息表增长过快造成存储空间的压力,因此通常都会设置审计条件,当条件触发时再发起审计。例如我们可以对 Account 表的 Balance 列设置审计条件,当访问该列并触发审计条件时才进行审计。如下所示:
begin
dbms_fga.add_policy (
object_schema=>'TEST',
object_name=>'ACCOUNT',
policy_name=>'ACCOUNT_ACCESS',
audit_column => 'BALANCE',
audit_condition => 'BALANCE >= 11000'
);
end;
该策略将在访问 BALANCE 列并且只有访问列值大于等于11000 时才发起审计。因此根据该条件户有如下不同审计状态:
SQL 语句 | 审计状态 |
select balance from account; | 进行审计。用户选择了在添加策略时所指定的审计列 BALANCE 。 |
select * from account; | 进行审计。即使用户没有明确指定列 BALANCE ,* 也隐含地选择了它。 |
select cust_id from account where balance < 10000; | 进行审计。即使用户没有明确指定列 BALANCE ,where 子句也隐含地选择了它。 |
select cust_id from account; | 不进行审计。用户没有选择列 BALANCE 。 |