现实问题的细粒度审计,第 2 部分 作者:Arup Nanda 在掌握了基本概念之后,了解细粒度审计中的高级概念,并解决应用程序用户模型中的问题。 在本系列的 第 1 部分 中, 我说明了如何构建一个细粒度审计 (FGA) 系统以审计选择语句,并根据特定的条件捕获语句。在常规的审计中或通过使用 DML 触发器和 Log Miner 工具,上述工作几乎不可能完成。除了创建审计跟踪,我们还了解了当满足审计条件时,如何让审计跟踪执行一个用户定义的过程。 在这一部分内容中,我们将探讨高级的 FGA 概念,如应用程序用户模型和重建用户查看的数据。 应用程序用户问题 上篇文章解释了如何构建一个 FGA 系统,从而在表 FGA_LOG$ 中记录发出查询的数据库用户。在数据库用户映射到一个物理用户的情况下,这一方法非常有效。但是,在有些情况下(如在基于 web 的应用程序中),应用服务器使用固定的用户 id(如 APPUSER)连接到数据库。应用程序用户由应用程序验证。例如,用户 SCOTT 连接到应用程序,应用程序验证用户,然后使用用户 id APPUSER 连接到数据库。如果在此环境中使用了 FGA,FGA 将显示用户为 APPUSER 而不是 SCOTT。同样,另一个选择数据的应用程序用户 JANE 也将被记录为 APPUSER 而不是 JANE。由于记录的用户名不是实际的用户,审计没有发挥作用。 立刻迸入脑海里的解决方案是在数据库中创建应用程序用户,让应用程序使用用户 id 和口令连接到数据库。例如,在上述示例中,用户 SCOTT 和 JANE 将是数据库中的用户,无需存在一个名为 APPUSER 的用户。这一方法既简单又安全,因为数据库验证用户,并且不管连接采用何种方式,用户始终保持不变。 但是在该方法下,所有的用户都必须在数据库中创建,这将导致管理极其困难—尤其当用户数量达到几千人(这 在 web 应用程序中很常见)。此外,用户必须记住他们在不同地方的用户名和口令,这一麻烦正是一次性登录存在的全部理由。尽管使用 Oracle Advanced Security Option(ASO,也称为高级联网选项或者 ANO)以及 Oracle Internet Directory 可以解决这一问题,但是对于大多数网站,此解决方案不可行。 在 web 应用程序中,连接池的概念还需要使用一个普通的用户 id。如图 1 所示,应用服务器使用用户 APPUSER 创建了几个与数据库的连接。当应用程序用户(如 SCOTT)需要涉及数据库的服务时,应用程序使用与数据库的一个连接来完成请求。这一模型可以使用几个连接支持许多用户,因此受到 web 应用程序设计师的欢迎。但需要重申的是,这一方法不会在 FGA 中记录正确的用户名。 客户端标识符使用应用程序用户 id 的理由非常充分。因此,理想的解决方案是在 FGA 框架中使用应用程序用户 id,而不是绕过该需求。 Oracle9i 引进了 客户端标识符 (一个可以作为会话属性的值)的概念。任何值都可以放入该属性中,在我们的情况中,可以使用它来代表 实际的 用户名,如 JANE。尽管数据库用户名被记录为 APPUSER 或其它名字,客户端标识符可以存放值 JANE。 可以将会话的客户端标识符设置为某个值,方法是调用 Oracle 提供的 API dbms_session.set_identifier 。下列语句设置了会话中的标识符 SCOTT: EXECUTE DBMS_SESSION.SET_IDENTIFIER ('SCOTT')
设置完以后,此标识符将在该会话的 V$SESSION 视图中显示。 SELECT CLIENT_IDENTIFIER
FROM V$SESSION
WHERE AUDSID = USERENV('SESSIONID');
显示的值为 SCOTT,正如前面所设。那么,该值的重要性体现在哪里?除了出现在 V$SESSION 视图中,此信息还会显示在 FGA 表 FGA_LOG$ 以及随后的 DBA_FGA_AUDIT_TRAIL 视图的 CLIENT_ID 列中,如下所示: SELECT DB_USER, CLIENT_ID FROM DBA_FGA_AUDIT_TRAIL;
尽管 DB_USER 列显示了 数据库 用户,真正的 应用程序 用户(如果放在标识符中)可以在 FGA 跟踪中捕获。当审计应用程序用户时,这是一个需要理解和应用的非常重要的概念。 客户端标识符还出现在常规的审计跟踪中,而不仅仅出现在细粒度的审计跟踪中。因此,在各种审计情况下(从 常规类型到高级的细粒度类型),这个值都提供缺少的链接来表示实际的用户。在常规的审计跟踪中,表 AUD$ 在列 CLIENTID 中记录了客户端标识符(如果在会话中已设置)。该值显示在相关的视图中,如列 CLIENT_ID 中的 DBA_AUDIT_TRAIL。 令人感到困难的是如何正确地设置这一值。请记住,在一个启用 web 且具有连接池的应用程序中,数据库会话服务于许多用户会话—在会话之初仅设置一次值没有作用。此外,应用程序必须在每次调用数据库之前设置客户端标识符, 从而 FGA 能够看到真正的应用程序用户 id。当另一个应用程序线程重用数据库会话时,标识符被设置为另一个用户 id,标识 FGA 跟踪中的该名用户。 另一种方法是设置一个 cookie,并使用该值设置客户端标识符。这种方法更安全,因为 cookie 可以包括其它的验证信息,而通过常规的会话根本不可能设置这些信息。然后,可以正确地解码标识符中的值,获得真正的用户名;但是验证信息为该值添加了一个 数据完整性组件。 应用程序环境 使用客户端标识符有它的优点,但也存在严重的安全威胁:这种设置假定用户将值设为真正的用户 id,但这一点无法得到保证。恶意攻击的用户可以连接然后将该值设为不同的用户 id,严重地破坏审计跟踪的真实性。在 web 应用程序中,使用 cookie 存储客户端标识符使得破坏更困难(如果不是不可能);但是在普通的应用程序中,仅仅使用客户端标识符,安全性可能不尽人意。我们需要一种更安全的方法来捕 获审计跟踪中的应用程序用户。 进入解决方案: 应用程序环境 .应用程序环境类似于会话变量;一旦设置了,任何时候都可以在会话中访问它们。可以在另一个会话中设置一个不同的值,而在整个会话中都看不到这个值。环境具有的属性类似于表的列;但与表不同的是,环境不是片段对象,属性可以在运行时而不是设计时定义。 可以使用下列 SQL 创建应用程序环境: create context my_app_ctx using set_my_app_ctx;
注意,子句 using set_my_app_ctx 意味着环境中的属性 只能 通过名为 set_my_app_ctx 的过程来操作,该过程定义如下: create or replace procedure set_my_app_ctx
(
p_app_user in varchar2 := USER
)
is
begin
dbms_session.set_context('MY_APP_CTX','APP_USERID', p_app_user);
end;
此过程通过调用 dbms_session.set_context API,简单地将属性 APP_USERID 设置为输入参数传递的值。因此,如果用户直接调用此 API,其结果会如何呢? SQL> exec dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE')
BEGIN dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE'); END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 78
ORA-06512: at line 1
注意错误 ORA-01031:insufficient privileges 有点令人误解。用户的确对 SYS.DBMS_SESSION 有执行权限,但是通过调用它来设置环境属性是违法的,因此出现了错误。但是,当用户调用受信任的过程来设置环境属性: SQL> execute set_my_app_ctx ('AAAA')
PL/SQL procedure successfully completed.
设置成功了。因为环境属性只能通过它的过程(正确叫法是 受信任的 过程)来设置。这是应用程序环境一个非常重要的属性,将在 FGA 中得到使用。 一旦设置了环境属性,可以通过调用函数 SYS_CONTEXT 来检索它。在上述代码中设置完环境后,可以通过下列语句来查看环境: select sys_context('MY_APP_CTX','APP_USERID') from dual;
该语句返回属性值。如果可以通过安全的方式设置环境,则可以利用环境来设置客户端标识符。 基于我们现有的知识,以下是可能的解决方案:
- 应用程序执行过程代码,该代码自动地将应用程序环境设置为正确的值。在上述示例中,使用了用户 id 的环境属性,但另一个属性—如用户的角色—可能已经被使用了。可以在一个环境中定义多个属性。可以将属性作为启用的角色使用。受信任的过程可以包括各种类 型的安全检查,从而使得它安全且真实可信。如果安全检查失败了,则不能设置所需的角色。因此,即使用户可以使用 APPUSER 帐号成功地登录,他也不能够操作数据,因为没有启用适当的角色。注意,角色必须经过过程认证,而不能是普通的角色。这种角色由命令 CREATE ROLE USING 创建;用户通过调用 而不是 SET ROLE 命令启用角色。
-
- 此过程也设置客户端标识符,因此没有必要授予公众对 dbms_session 的执行权限,即使对此用户也没有必要。由于用户没有权限调用 API,他们不能直接设置客户端标识符—客户端标识符将被自动设置,并且传递到细粒度的审计跟踪。
这一方法可以使用用户定义的审计跟踪得到进一步的完善。其中客户端标识符可以被设置为从应用程序环境中检索到的值。我们将在本系列的第三部分(以及最后一部分)中讨论该方法。 用户看到的状况如何呢? 细粒度的审计跟踪记录用户连同绑定变量的值(如果存在)一同输入的实际语句。下面是从跟踪中可以捕获的一条典型语句: select balance from accounts
where acct_no = 10034;
假设这一事务处理发生在 10:00AM,而现在是 11:00AM。在这种情况下,帐户余额可能已经更新了。如果审计员(或者 DBA)决定查看用户在 那一时刻 看到的实际情况,列的当前值可能没有反映准确的信息。在工业间谍的情况中,或者要建立动机或模式,用户非常有必要看到确切的数据。即使 FGA 没有捕获该时刻的准确数据,我们也可以使用跟踪中捕获的另一条信息看到该数据。 在本系列的第 1 部分 中, 我们看到了视图 DBA_FGA_AUDIT_TRAIL 的结构。该视图记录了与会话和用户相关的几条关键信息。此处的相关列是 SCN,它记录了生成跟踪时的系统更改号。使用闪回查询,我们可以重建该点时刻的数据。假设审计跟踪中 SCN 的值为 123456,我们可以如下所示进行查询: select balance from accounts as of SCN 123456
where acct_no = 10034;
SCN 123456 的子句将从表中返回该点时刻而不是现在的余额,这正是我们所需要的。 由于闪回局限于撤消保留时段,在该时段外发生的事务会丢失。但是,审计员可能寻找自事件发生 后 的跟踪,因此,使用闪回仅捕获重要的列,执行一次定期的审计收集是比较谨慎的做法。 下一次内容 在第 3 部分中,我将讨论用户定义的 FGA 实用程序,以及 Oracle Database 10g 中令人兴奋的新 FGA 特性。 现实问题的细粒度审计,第 3 部分 作者:Arup Nanda 现在您已经掌握了各种环境中的 FGA,下面您将了解到它如何能够在 Oracle Database 10g 中起到更大的作用 在本系列的前两个部分中,我向您介绍了细粒度审计 (FGA) 的概念,它用来在 Oracle9i Database 和更高版本中跟踪选定的语句。我还说明了如何在复杂的环境中(比如说在一个 Web 应用程序内部)通过应用程序上下文和客户端标识符来使用这个特性。这两篇文章为您提供了足够的信息,使您可以为几乎所有类型的数据库系统(无论它有多复 杂)构建一个 FGA 设置程序。在这个第三部分,同时也是最后一部分中,我将说明 Oracle Database 10g 为表带来的 FGA 增强。 Oracle9i Database 中的 FGA 让我们简要地重述一下 FGA 的好处。关于完整的讨论,请参考本系列的第 1 部分 和第 2 部分 。 正规审计(通过 AUDIT 语句)记录使用的语句 — 如 SELECT 或 INSERT — 以及谁发出它、从哪一个终端、什么时候等等。然而,信息最重要的部分 — 哪条 特定 记 录被修改了,以及数据本身的变化 — 没有捕获到。相反,许多用户编写触发器来捕获变化前后的数据值,并把它们记录在用户自定义的表中。但因为触发器只可能在 DML 语句(如 insert、update 和 delete)上使用,所以访问的一个主要的方面 — SELECT 语句 — 不能通过这种途径来审计。 因此 FGA 的价值在于:它只捕获 SELECT 语句。与触发器和 Log Miner 工具一起,FGA 提供了一种机制来审计各种类型的值修改和不涉及到修改的数据访问。 FGA 不仅填补了审计 SELECT 语句的空白,而且还提供了其它的一些引人注目的额外好处,这些好处使得数据库管理员的工作变得更加轻松。例如,FGA 允许一个用户自定义的过程在指定的审计条件出现的时候执行,因此您可以认为它是 SELECT 语句上的一个触发器 — 这是一个在其它方式下没有提供的功能。这个技巧可能非常有用 — 例如,任何时候当有人选择了收入超过 1 百万美元的员工的工资记录时,发送一封邮件给一个安全审计员,以在用户自定义的表中生成审计记录,这些表可以不受限制地进行处理(这与 SYS 拥有的 FGA_LOG$ 表不同);利用审计线索识别数据访问类型,以找出最可能的索引机制等等。 由于这些及其它的原因,FGA 成为数据库管理员工具箱中最重要的工具之一。不过,在 Oracle9i Database 中,它缺少一个重要的特性:在 SELECT 语句之外的语句上使用。 所有类型的 DML 在 Oracle Database 10g 中,FGA 已变得很完善 — 它可以审计所有类型的 DML 语句,而不只是 SELECT。 让我们看一个例子。在本系列的第 1 部分 中,我介绍了一个名称为 ACCOUNTS 的表。在那个表上定义的 FGA 策略为: begin
dbms_fga.add_policy (
object_schema => 'BANK',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_ACCESS',
audit_column => 'BALANCE',
audit_condition => 'BALANCE >= 11000'
);
end;
在 Oracle 9i Database 下,这个策略只能审计 SELECT 语句。然而,在 Oracle Database 10g 中,您可以扩展它,使它包含 INSERT、UPDATE 和 DELETE。您可以通过指定一个新的参数来实现这个目的: statement_types => 'INSERT, UPDATE, DELETE, SELECT'
这个参数将在所有包括的语句类型上启用审计。您甚至可能考虑为每种语句类型创建单独的策略,这将允许您随意地启用和禁用策略 — 尤其是,控制审计线索的创建,以管理它们占用的空间。不过, statement_type 参数默认情况下只审计 SELECT 语句。 在策略中添加新的参数之后,发出以下语句: update accounts set balance = 1200 where balance >= 3000;
这将使一条记录插入到 FGA_LOG$ 表中。注意这条记录是由一个自动事务插入的;即使您回滚 update 语句,这条记录也将存在。您可以从另一个会话来检查线索是否存在。 select lsqltext from fga_log$;
LSQLTEXT -------------------------------------------------------- update accounts set balance = 3100 where balance >= 3000
该行还包括其它所有的相关详细信息(如表名称、策略名称和事务 ID)。 与触发器方法相比较 那么 FGA 能做什么原来的基于触发器的方法不能做的事情? 在 Oracle Database 10g 之前,DML 语句审计是在一个触发器中进行的,类似于以下方式(注意:这不是真实的代码,只是一个代表性的示例): CREATE TRIGGER XXXXX
ON Table
AFTER INSERT OR UPDATE OR DELETE
FOR EACH ROW
BEGIN
INSERT INTO AUDIT_LOG
Old Value, New Value, Time .....
END
触发器捕获旧的值和新的值,并填充 AUDIT_LOG 表。如果需要,还可以将它变为自动事务。最大的问题是触发器是对每行触发的,而不是每条语句一次。例如,以下语句: update accounts set balance = 1200 where balance >= 3000;
对全部 10,000 条记录触发,在审计表中插入 10,000 行。这种方法可能严重地损害 update 语句的性能,甚至可能因审计线索中的空间问题而导致失败。使用语句触发器也无济于事,因为它不能捕获个别记录的任何新的或旧的值。比较而言,在 FGA 方法中,只创建一条记录,并且插入只在每条语句上执行一次,而不是每行一次 — 即使有的话,对性能的影响也很小。 在 FGA 中,您可以指定相关的列来限定审计线索仅在这些列被访问时才创建。在触发器中,通过使用触发器定义的 WHERE,这种功能也可以实现。不过,其中存在一个非常重要的差异 — 在触发器中,只有 当列被修改时(而不是被访问时)才检查它们。在 FGA 中,无论何时列被访问(无论它们被修改与否),审计就开始。这个特性使得 FGA 比触发器具有更多的功能。 另一个优点是 FGA 工具的适用性。有时,在一个视图上定义的 INSTEAD OF 触发器在基表上更新视图;另一个 INSTEAD OF 触发器不能捕获由其它的触发器所作的修改,因此这些修改不能被记录。然而,FGA 是建立在视图或表的基础上的,它能够捕获变化,而不论变化来自哪里 — 用户语句或触发器。 那么,是否存在触发器比 FGA 更好的情况呢?可能有两种情况:
- 记住,FGA 通过一个自动事务来插入审计线索,这种事务在它自己的上下文中提交。当 DML 语句失败或被回滚时,插入的线索记录 不 被 回滚。如果用户更新了一些东西但没有提交,则不执行修改,但不管怎样,将创建审计线索。这可能导致在审计线索中产生几个虚假的实际项目 — 一种不希望出现的潜在情况。随后使用通过闪回查询捕获的 SCN 号码对表进行分析将可能揭露这个问题,但这个过程可能非常复杂。但如果这种风险是不可接受的,那么基于触发器的方法将优于 FGA 成为首选。
-
- FGA 记录用户发出的 SQL 语句和 SCN 号码,但不记录在修改之前和之后的值。必须使用一个单独的工具来从表中通过闪回查询取出这些值。因为闪回查询依赖于 UNDO 段中包含的信息(这些信息是有限的),因此这个工具可能不会从过去很久的时间点上取出旧的值。基于触发器的方法在源数据上捕获变化,因此保证旧的值和新的 值都有记录。
在变化期间 FGA 的行为 数据始终在变化,因此它有可能变得适用于审计条件 — 虽然之前它不适用于审计条件,反之亦然。这个问题带来了一些关于 FGA 在不同情况下的行为的有趣问题。考虑我们的例子,其中在 UPDATE 上已经定义了 FGA 策略,条件为 BALANCE >= 3000,审计列是 BALANCE。 第 1 种情况 之前:BALANCE = 1000 用户发出: update accounts set balance = 1200 where ACCOUNT_NO = ....
旧的和新的 balance 都小于 3,000,审计条件不满足;因此这条语句将 不会 被审计。 第 2 种情况 之前:BALANCE = 1000 用户发出: update accounts set balance = 3200 where ACCOUNT_NO = ....
新的 balance 大于 3,000,审计条件满足;因此这条语句将 会 被审计。 第 3 种情况 之前:BALANCE = 3200 用户发出: update accounts set balance = 1200 where ACCOUNT_NO = ....
新的 balance 小于 3,000,但旧的 balance 大于 3,000。因此审计条件满足,这条语句将被审计。 第 4 种情况 用户插入一行,其中有 BALANCE < 3000。 insert into accounts values (9999,1200,'X');
因为 balance 1,200 不满足审计条件,所以这条语句不被审计。如果 balance 列大于或等于 3,000,它将被审计。 第 5 种情况 用户插入一行,其中 balance 的值为空。 insert into accounts (account_no, status) values (9997, 'X');
因为 balance 为空,该列没有任何默认值,所以审计条件不满足(比较 NULL >= 3000 结果为 FALSE),这条语句不会被审计。 重要注意事项 :假设该列 有 一个大于 3,000 的默认值时,这条语句仍然不会被审计,即使插入行的 balance 列值大于 3000。 所有相关的列? 考虑在表 ACCOUNTS 上定义的一个策略,如下: begin
dbms_fga.add_policy (
object_schema => 'ANANDA',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_SEL',
audit_column => 'ACCOUNT_NO, BALANCE',
audit_condition => 'BALANCE >= 3000',
statement_types => 'SELECT'
);
end;
您可以看到,策略是在 ACCOUNT_NO 和 BALANCE 上定义的。假定帐户 9995 的余额是 3,200,如果用户发出以下语句: select balance from accounts where account_no = 9995;
这条语句将被审计,因为 balance 列被选中,且余额为 3,200,大于 3,000,满足审计条件。不管这三个列中哪一个被选中,都将触发审计。 在某些情况下,列的组合可能很重要,而不是某个特定的列。例如,如果一个用户想查出在银行的总余额,她发出: select sum(balance) from accounts;
这条查询几乎没什么害处;它不明确指出帐户所有者和帐户余额。Acme Bank 安全策略可能不会要求审计这条查询。不过,这条查询 select balance from accounts where account_no = 9995
必须被审计;因为它明确地指定了一个帐户。默认地, 所有 语句都被审计(无论使用了什么样的列组合)。这将创建大量不需要的审计线索项目,并可能带来一些空间限制问题。为了限制它们,您可以指定仅当在查询中使用了希望的列组合时才开始审计。当定义策略时,您可以使用一个新的参数: audit_column_opts => DBMS_FGA.ALL_COLUMNS
这个参数将使策略仅当列 ACCOUNT_NO 和 BALANCE 在查询中都被访问时才创建审计线索项目。例如,以下查询将产生一个审计线索项目。 select account_no, balance from accounts;
但这条查询不会产生审计线索项目。 select account_no from accounts;
使用这个参数将把审计的数量限制在一个更易管理的大小。如果希望采用默认的行为 — 即任意列被选中时都进行审计,那么您可以对同一参数的使用不同值。 audit_column_opts => DBMS_FGA.ANY_COLUMNS
捕获赋值变量 利用 Oracle Database 10g ,其它的有用信息(如在查询中使用的赋值变量的值)可以写到常规的审计线索中。您可以通过设置初始化参数来执行这项任务 audit_trail = DB_EXTENDED
在 FGA 审计线索中,获取赋值变量的值可能有意义也可能没意义。如果您想要停止记录这些值,您可以在add_policy() 过程中使用另一个参数,如下: audit_trail => DB
默认情况下,捕获赋值变量,这个参数的值为 DB_EXTENDED。 全部综合在一起 现在您已经了解了 Oracle Database 10g 中的几个新的 FGA 参数,下面让我们看看策略创建脚本的声明现在是什么样子。 下面我们定义对应四种语句类型的四种不同的策略。SELECT 语句的策略显示如下,这里我们选择了不记录赋值变量的值,并仅当列 ACCOUNT_NO 和 BALANCE 在查询中都被使用时才触发审计。 begin
dbms_fga.add_policy (
object_schema => 'ANANDA',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_SEL',
audit_column => 'ACCOUNT_NO, BALANCE',
audit_condition => 'BALANCE >= 3000',
statement_types => 'SELECT',
audit_column_opts => DBMS_FGA.ALL_COLUMNS,
audit_trail => DB
);
end;
同样,我们将为 INSERT、UPDATE 和 DELETE 语句创建类似的策略。它们可以随意地启用或禁用。 结合常规审计和细粒度审计 在 Oracle Database 10g 中,常规审计也得到了巨大的改进。通过 AUDIT 命令执行常规审计,它现在能够捕获大量其它有用的信息,例如:
- 扩展的细粒度时间戳记
- 操作系统进程 ID
- 事务标识符(当审计线索被一个数据修改事务(如通过一次更新)创建时,事务 ID 在此时被记录,记录的事务 ID 在之后可以和视图 DBA_TRANSACTION_QUERY 结合来识别确切的语句、它的撤消 SQL、行 ID 等等)
- SQL 语句正文
- 赋值变量的值
- 修改时的 SCN。
您可以看到,在内容和功能方面,常规审计类似于细粒度审计。然而,作为一个数据库管理员,您有兴趣知道所有的审计项目,而不只是一个审计项目。一个新的视图, DBA_COMMON_AUDIT_TRAIL ,结合了常规线索和 FGA 线索。用以下查询来检查它们二者: select * from dba_common_audit_trail;
这个视图结合了 DBA_AUDIT_TRAIL 和 DBA_FGA_AUDIT_TRAIL,拥有来自每个视图的相关信息。这个视图从数据字典中创建,如下所示。 select 'Standard Audit', SESSIONID,
PROXY_SESSIONID, STATEMENTID, ENTRYID, EXTENDED_TIMESTAMP, GLOBAL_UID,
USERNAME, CLIENT_ID, Null, OS_USERNAME, USERHOST, OS_PROCESS, TERMINAL,
INSTANCE_NUMBER, OWNER, OBJ_NAME, Null, NEW_OWNER,
NEW_NAME, ACTION, ACTION_NAME, AUDIT_OPTION, TRANSACTIONID, RETURNCODE,
SCN, COMMENT_TEXT, SQL_BIND, SQL_TEXT,
OBJ_PRIVILEGE, SYS_PRIVILEGE, ADMIN_OPTION, GRANTEE, PRIV_USED,
SES_ACTIONS, LOGOFF_TIME, LOGOFF_LREAD, LOGOFF_PREAD, LOGOFF_LWRITE,
LOGOFF_DLOCK, SESSION_CPU
from DBA_AUDIT_TRAIL
UNION ALL
select 'Fine Grained Audit', SESSION_ID,
PROXY_SESSIONID, STATEMENTID, ENTRYID, EXTENDED_TIMESTAMP, GLOBAL_UID,
DB_USER, CLIENT_ID, EXT_NAME, OS_USER, USERHOST, OS_PROCESS, Null,
INSTANCE_NUMBER, OBJECT_SCHEMA, OBJECT_NAME, POLICY_NAME, Null,
Null, Null, STATEMENT_TYPE, Null, TRANSACTIONID, Null,
SCN, COMMENT$TEXT, SQL_BIND, SQL_TEXT,
Null, Null, Null, Null, Null,
Null, Null, Null, Null, Null,
Null, Null
from DBA_FGA_AUDIT_TRAIL
FGA 和常规审计:差异 如果标准审计和细粒度审计在 Oracle Database 10g 中是类似的,您可能要问,在什么情况下,FGA 将是更好的选择?好的,让我们研究一下它们的差异。
- 标准审计必须用参数 AUDIT_TRAIL 在数据库级启用。这个参数不是动态的;您必须重启数据库来使其生效。相比而言,FGA 不需要任何参数修改。
-
- 一旦被设置在一个对象上,标准审计将保持在那里。要解除它,您必须用 NOAUDIT 命令删除审计选项。这可能很不方便,因为在一个表上丢弃审计选项也将丢弃元数据信息。然而,FGA 可以临时 禁用 和启用,不丢失任何元数据信息。
-
- FGA 只能够处理四种类型的语句:SELECT、INSERT、UPDATE 和 DELETE。相比而言,常规审计可以处理其它许多语句和权限,甚至会话连接和断开。
-
- 标准审计每次会话只创建一条记录(按会话)或每次访问对象创建一条记录(按访问)这种占用资源很少的方式对于控制审计线索表中的空间非常重要。FGA 并不是同样节省资源;它每次访问运行一次 — 使得线索更大。
-
- 通过记录线索,标准审计可以用来检测任何中断企图,如果企图没有成功,则将产生错误代码。而 FGA 不能。
-
- 标准审计可以写数据库表或 OS 文件。后者在审计员(不是数据库管理员)能够访问线索时非常有用。在 Windows 下,非数据库审计线索记录在事件日志中,并且可以用不同的方式对其进行访问。这个选项保护了审计线索的完整性。然而,FGA 日志仅写到数据库表 FGA_LOG$ 中。您可以在 FGA 中创建用户自定义的审计处理程序来写 OS 文件,但它们的完整性不能保证。
-
- 标准审计可以设置用于默认对象。当表是在运行期创建时,这个功能变得极为有用:默认的审计选项允许没有数据库管理员干预的审计。这在 FGA 中是不可能的,用户必须在一个现有的表上创建策略,上述的情况只能在表已创建之后才可能发生。
-
- 在 FGA 中,审计更加灵活 — 仅当访问某些列,当某个特定的条件为真时等等。这种多功能性在您需要控制线索的增长时非常方便。
-
- 在 FGA 中,SQL 赋值变量默认被捕获。在常规审计中,必须把初始化参数 audit_trail 设为db_extended ,以启用这一功能。
-
- 权限差异:常规审计需要审计系统或语句权限;FGA 只需要 dbms_fga 程序包上的运行权限。
通过上面的比较,您将了解为什么可以证明 FGA 在某些情况下很有用。利用 Oracle Database 10g 中的增强的常规审计特性,一些以前认为不可能的任务 — 例如捕获赋值变量的值 — 变得十分容易。 |