ITPub博客

首页 > IT职业 > IT生活 > 这一阶段在四个阶段中也是最长的

这一阶段在四个阶段中也是最长的

原创 IT生活 作者:davies 时间:2007-04-11 20:00:59 0 删除 编辑
这一阶段在四个阶段中也是最长的[@more@]

您终于走到最后阶段了,这一阶段在四个阶段中也是最长的。在这一阶段您我们要完成某些更加复杂的设置,并做长期规划以消除潜在威胁。

这一部分内容包括:
· 4.1 实现细粒度审计
· 4.2 激活虚拟专用数据库
· 4.3 屏蔽敏感的列
· 4.4 对敏感数据进行加密
· 4.5 安全备份
· 4.6 从归档日志中挖掘历史
· 4.7 结论

4.1 实现细粒度审计

背景您可能已经注意到,本文到现在还没有涉及到作为审计机制的触发器。为什么? 因为使用触发器,就意味着 再次 连续地执行 SQL,这增加了整个执行时间。 对生产系统来说,该开销几乎是不可以接受的。

因为细粒度审计 (FGA) 有最小的性能开销,所以在这里它是一个优秀的解决方案。 如果您已经熟悉 FGA,请跳过这一部分,直接阅读策略部分。

Oracle9i 数据库中引入了 FGA 特性,当用户对表进行选择和更改操作时,它将记录一个审计线索。因这一特性是唯一可记录选择活动的方法,所以它具有里程碑式的意义。 SELECT 语句上的常规审计功能仅仅记录 谁 针对对象发出了语句,但是不记录发送了 什么 语句。

除开详细信息(例如用户名、终端,以及查询时间)之外,FGA 还记录执行过的 SQL 语句和时间实例的 SCN 数量。 当您使用闪回查询重建数据之后,你不仅看到用户提交的语句,还有用户得到结果值。 在 Oracle 数据库 10g 第 1 版对该功能进行了扩展,涵盖其它 DML 语句,例如 插入、更新,以及 删除。

下面提供了一个小示例: 假设模式 BANK 有一个 ACCOUNTS 表。

Name Null?类型

---------------- -------- ------------

ACC_NO NOT NULL NUMBER

CUST_ID NOT NULL NUMBER

BALANCE NUMBER(15,2)

为了对其进行审计,您将需要使用提供的程序包 DBMS_FGA 定义相关 FGA 策略。

begin

dbms_fga.add_policy (

object_schema=>'BANK',

object_name => 'EMP',

policy_name => 'ACCOUNTS_ACCESS',

);

end;

以上代码执行完毕之后,将在 ACCOUNTS 表启用 FGA。 也就是说,没有必要对任何初始化参数进行更改,或对该数据库进行回弹。

执行以上代码时,它们在该表上使用共享锁定,因此您可以在线执行。现在,如果一个名为 ARUP 的用户提交以下语句,对该表中进行选择操作:

select * from bank.accounts;

该行动立即记录在称为 FGA Audit Trail的审计追踪中。 您可以使用以下语句对其进行检查:

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

--------- ------- ------- ------- -------- ---------------------------

08-FEB-06 ARUP arup BANK ACCOUNTS select * from bank.accounts

该视图也显示许多其它列。

您可以使用多种方法对 FGA 进行配置。 例如,如果您希望记录用户选择 BALANCE 列且余额超过 20,000 时的操作,你可以另外添加一些参数,同时定义 FGA 策略如下:

begin

dbms_fga.add_policy (

object_schema =>'BANK',

object_name => 'EMP',

policy_name => 'ACCOUNTS_ACCESS',

audit_column => 'BALANCE',

audit_condition => 'BALANCE >= 20000'

);

end;

FGA 的另一个特性就是当条件满足时,FGA 还能在审计线索中进行记录之外调用存储过程。在有额外处理(例如发送电子邮件)的情形,这一特性的效果极其显著。 这样的 SP 被称为 FGA 策略的 处理模块。 请记住,选择语句可以激活 FGA,也可以激活这些处理器模块。在某种意义上说,这使处理器模块“选择触发器”语句。

Oracle 数据库 10g 也介绍更多的 FGA 增强特性,例如这两个值得关注的特性:

绑定变量。 使用 FGA,您可以通过在 DBMS_FGA.ADD_POLICY 过程中使用参数来捕获语句中的绑定变量。

audit_trail => DB_EXTENDED

然后您可以将它们放到数据库初始化文件中,这样 FGA 可以一直对它进行记录。

相关列。 请看以下两个语句:

select balance from accounts where account_no = 9995;

select sum(balance) from accounts;

很明显,第一条语句请求了具体的敏感信息(基于此信息可识别客户),您可能想编辑该信息。第二条语句危险系数较低,用户使用该语句找不到关于该客户的任何具体的敏感数据。 按照您的安全策略,您可能希望记录第一条语句,不记录第二条语句。 这样有助于限制该线索的大小。

要完成这一任务,您可以使用另外一个参数 audit_column_opts => DBMS_FGA.ALL_COLUMNS,同时定义策略如下:

begin

dbms_fga.add_policy (

object_schema => 'ANANDA',

object_name => 'EMP',

policy_name => 'ACCOUNTS_ACCESS',

audit_column => 'BALANCE',

audit_condition => 'BALANCE >= 20000'

statement_types => 'SELECT');

audit_column_opts => DBMS_FGA.ALL_COLUMNS

);

end;

默认情况下为 DBMS_FGA.ANY_COLUMNS,无论 哪个 列被选择,它都能触发审计线索。

到这里我们只是精浅地涉及了 FGA。 要对 FGA 有一个全面的了解,获取更多的的示例,请参阅我的系列文章“对实际问题进行细粒度审计。”,分为三章。 " 同时我在 Oracle PL/SQL for DBAs (2005, O'Reilly Media) 一书中也对此也进行详细的讨论。

策略和常规审计相比,FGA 的最大优点是它不需要任何特定的初始化参数,所有它不需要数据库回弹。 您可以按需在对象上启用或禁用 FGA 策略。

您需要查找具体的敏感列和且有选择地查找这些列中的敏感值。首先,您需要制定审计策略。 下面是一个典型的策略示例:

在 SALARIES 表中:

  • 如果某个用户 仅 选择 SALARY 和 BONUS 列时,您可以进行审计。 如果选择了其它的列,则不进行审计。
  • 甚至当用户仅选择一列(例如 SALARY 列),且无需任何可识别信息(例如 EMPNO)时,也进行审计。
  • 无论什么时候,只要用户从 EMPNOS 低于 1000(这些 EMPNO 用于管理人员)的表中选择任何列,仍然审计。
  • 如果选择了用户 SAP_PAYROLL_APP 项,则不要审计。 这是工资处理应用程序使用的用户 id, 对它进行审计将会生成大量的数据,并填满线索表。
  • 人力资源助手 Monica 和 Adam 定期检查和调整工资在 1,000 以下的低等级雇员的工资。您不应该审计工资在 1,000 以下的选择语句。
  • 除开审计,请您执行一个存储过程 enqueue_message,该过程向负责安全的官员发送电子邮件。

把该策略记住后,您应该创建两个不同的 FGA 策略。

首先,针对 EMPNO >= 1000、SALARY 列和 BONUS 列的通用策略。

begin

dbms_fga.add_policy (

object_schema => 'ACCMAN',

object_name => 'EMP',

policy_name => 'EMP_SEL_POL',

audit_column => 'SALARY, BONUS',

statement_types => 'SELECT');

audit_option => 'EMPNO >= 1000 and USER NOT IN(''SAP_PAYROLL_APP'', ''MONICA'', ''ADAM'')',

handler_module => 'ENQUEUE_MESSAGE'

);

end;

然后,针对 EMPNO < 1,000 创建用于全部列的策略。

begin

dbms_fga.add_policy (

object_schema => 'ACCMAN',

object_name => 'EMP',

policy_name => 'EMP_SEL_POL',

statement_types => 'SELECT');

audit_option => 'EMPNO < 1000',

handler_module => 'ENQUEUE_MESSAGE'

);

end;

第三,给 MONICA 和 ADAM 添加特殊的策略。

begin

dbms_fga.add_policy (

object_schema => 'ACCMAN',

object_name => 'EMP',

policy_name => 'EMP_SEL_POL',

audit_column => 'SALARY, BONUS',

statement_types => 'SELECT');

audit_option => 'EMPNO >= 1000 AND SAL <= 1000 and USER IN

(''MONICA'', ''ADAM'') AND USER != ''SAP_PAYROLL_APP''',

handler_module => 'ENQUEUE_MESSAGE'

);

end;

正如您所看到的,audit_option 中的条件之间是相互排斥的,所以当用户尝试执行 SELECT 语句时,只有一个策略是有效的,也只有一条记录会被写入。

您可以使用该策略构建 FGA 策略集。 然后,您可以根据需要自由地启用或禁止策略,这不会影响操作。

问题主要有以下四个问题:

1. 当选择做出之后如果处理器模块(如果定义了)抛出错误,将会在 Oracle 不同版本中引起不同的行为:

o 在 Oracle9i 数据库中,处理器模块 以无提示的方式 停止对该行进行检索,不会报错。 因此,如果有 100 行,其中 4 行满足了审计条件,处理器模块运行四次,每次都会失败。 该查询将仅仅返回 96 行,而不报告任何错误,您将绝不会知道事情已经发生了。很显然,这种做法会产生不精确的结果。

o 在 Oracle Database 10g 第 1 版中,处理器模块将忽略处理器模块中的错误,按照预期检索所有 100 行。

o 在 Oracle Database 10g 第 2 版中,处理器模块将报告执行查询的用户会话方面的错误,而不返回任何行,甚至不返回那些不满足审计条件而没有执行处理器函数的 96 行。

所以,在实施 FGA 处理器模块之前请先对其进行全面测试。

2. 审计线索表——FGA_LOG$——在系统表空间中。当更多的 FGA 条目产生时,空间表就填满了,这可能导致数据库运行中断。

3. 审计线索被写入表中,不过是以异步方式进行的。 这会产生事务处理和 I/O,它将增加到数据库中的整体 I/O 中。 如果您的数据库是受 I/O 所限,您将看到实施 FGA 处理器模块后对整个数据库的性能影响。

4. 您可以使用自治事务处理以异步方式编写审计线索。 所以,即使用户回滚该事物处理,也不会删除该线索条目,导致错误的正值.如果您想将 FGA 用作一种简单的机制来识别用户,您应该注意这些错误的正值。

操作清单

1. 识别敏感的表和列。

2. 识别要访问的敏感度——例如,工资低于 500 的。

3. 将所有可能的组合放在一张纸上,然后将这些组合合并成 WHERE 条件(谓词),在这种方式下,只要一个谓词就将满足任何给定的条件。

4. 在那些谓词中构建 FGA 策略。

5. 启动 FGA 策略。

6. 之后,分析 FGA 审计线索文件。

7. 制作清除计划,清除 FGA 线索表。


4.2 激活虚拟专用数据库

背景如果您已经很熟悉应用程序环境和虚拟专用数据库(也称为行级安全性或细粒度访问控制),您可以跳过该节,直接查看策略节。

虚拟专用数据库 (VPD) 是一个很大的主题,因此我在这里只将一些基本的。 要了解背景知识,请参考我的 Oracle 杂志中有关该主题的 文章;您也可以在我的书里面找到关于 FGA 方面的更多信息。

假设您有一个称为 ACCOUNTS 的表,表中有以下数据:

SQL> select * from rates;

ACCNO ACC_NAME ACC_BAL

---------- -------------------- ----------

1 John 1000

2 Jill 1500

3 Joe 1200

4 Jack 1300

您想确保只有得到适当授权的人才可以查阅授权范围的帐户余额。也就是说,级别 1 看到的余额应该小于 1,000,级别 2 看到的余额应该小于 1,200,级别 3 可以看到所有的余额。 您还有另一张显示用户和级别的表。

SQL> select * from tab;

USERNAME USERLEVEL

------------------------------ ----------

CLERK1 1

CLERK2 2

CLERK3 3

要存储用户首次登录时的用户级别,因此需要创建应用程序环境:

create context user_level_ctx using set_user_level_ctx;

以及相关的可信过程:

create or replace procedure set_user_level_ctx

(

p_level in number

)

as

begin

dbms_session.set_context (

'USER_LEVEL_CTX',

'LEVEL',

p_level

);

end;

接着,您需要创建登录触发器以设置适当的应用程序环境。

create or replace trigger tr_set_user_level

after logon

on database

declare

l_level number;

begin

select userlevel

into l_level

from arup.userlevels

where username = user;

set_user_level_ctx (l_level);

exception

when NO_DATA_FOUND then

null;

when OTHERS then

raise;

end;

这设置了一个阶段,您可以按照该阶段在应用程序环境属性设置用户级别。 我们测试一下,以确保:

SQL> conn clerk1/clerk1

Connected.

SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')

--------------------------------------

1

SQL> conn clerk2/clerk2

Connected.

SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')

--------------------------------------

2

SQL> conn clerk3/clerk3

Connected.

SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')

--------------------------------------

3

正如您可以看到的,每个用户 ID 都设置了相应的级别。 现在,您可以在表上构建 VPD。 您可以使用所提供的 PL/SQL 包 DBMS_RLS 控制整个 VPD 基础架构;一个称为策略的概念控制着决定应该显示哪些行的规则。 策略将“谓词”(WHERE 条件)应用到表中的所有查询上,有效地限制了对行的访问。一个称为策略函数的函数生成 WHERE 条件。 因此,首先我们必须创建策略函数,该函数返回 WHERE 条件以将该条件应用到查询中。

create or replace function get_acc_max_bal

(

p_schema in varchar2,

p_obj in varchar2

)

return varchar2

as

l_ret varchar2(2000);

begin

select

case userlevel

when 1 then 'acc_bal <= 1000'

when 2 then 'acc_bal <= 1200'

when 3 then null

else

'1=2'

end

into l_ret

from userlevels

where username = 'HR'

return l_ret;

end;

然后添加策略:

begin

dbms_rls.add_policy (

object_name => 'EMP',

policy_name => 'ACCOUNTS_ACCESS',

policy_function => 'USER_ONLY',

statement_types => 'INSERT, UPDATE, DELETE, SELECT',

update_check => TRUE

);

end;

这次表得到保护。 当 CLERK1 登录并从表中进行选择:

SQL> select * from arup.accounts;

ACCNO ACC_NAME ACC_BAL

---------- -------------------- ----------

1 John 1000

Clerk1 只能看到 ACCNO 1,余额为 1,000。因为没有授予 Clerk1 查看高于 1,000 的账户余额,所以他看不到其它账户。 但是,当 Clerk2 登录时:

SQL> conn clerk2/clerk2

Connected.

SQL> select * from arup.accounts;

ACCNO ACC_NAME ACC_BAL

---------- -------------------- ----------

1 John 1000

2 Joe 1200

她也可以看到 ACCNO 2。 ACCNO 2 的余额为 1,200,在给 Clerk2 的授权限制之内。

您可以使用该技术将被限制的视图类放到表中。在项目锁定中,这将是一个很方便的工具。

策略关键是找出各方面的哪些信息将被保护,哪些列上的信息将被保护。 这听起来很简单,但是实际做起来是很难的。 收集该信息需要商业知识,或者合作者至少要更熟悉那些过程。一旦您识别到表和列,您应该能够按照以上背景部分中示例中显示的那样实施 VPD 策略。

即使 VPD 是很效的,如果您想让一些用户可以不受限制就可以访问表怎么办? 角色 EXEMPT ACCESS POLICY 的确是这样做的。

grant exempt access policy to ananda;

从此处开始,ANANDA 将跳过在所有表中定义的所有访问策略。

使用户跳过所有访问限制可能是不可接受的,然而,一个更好的解决方案是在策略函数中对其进行编码。一个很好的示例就是表的模式所有者——无疑您想该所有者看到表的所有行而不受到限制。 您可以在策略函数中对其进行如下编码:

create or replace function get_acc_max_bal

(

p_schema in varchar2,

p_obj in varchar2

)

return varchar2

as

l_ret varchar2(2000);

begin

if (p_schema = USER) then

l_ret := NULL;

else

select

case userlevel

when 1 then 'acc_bal <= 1000'

when 2 then 'acc_bal <= 1200'

when 3 then null

else

'1=2'

end

into l_ret

from userlevels

where username = 'HR'

end if;

return l_ret;

end;

当表的所有者登录 (p_schema = USER) 时,该版本函数返回 NULL,所以对表的访问不受限制。当然,您可以在该函数中进行任意更改,以允许更多用户跳过 VPD 策略。

VPD 的最大挑战是对子表进行限制。 您的限制条件可能在称为 ACC_BAL 的列上;但是所有其它子表不可能有该列。因此,您如何限制那些表?

例如,这里有一个称为地址的表,该表包含这些客户的地址。该表没有称为 ACC_BAL 的列,因此您如何对该表设置和 ACCOUNTS 表一样的限制? 有如下两种方式:

  • 将列 ACC_BAL 添加到地址表中。 您可以通过主表 ACCOUNTS 中的触发器对该列进行更新。 现在,您可以使用 ACCOUNTS 上使用的相同策略函数定义表中的策略。
  • 对 ADDRESSES 表使用不同的策略函数。 在该函数中,返回值应该是

ACCNO in (SELECT ACCNO FROM ACCOUNTS)

这是策略限制中使用的谓词。 因此,VPD 将只显示表上的账户地址。而且因为无论如何 VPD 限制了表 ACCOUNTS,所以 VPD 将自动限制表 ADDRESSES。

您必须按照自己所处的环境从这两种方法中选取一种。

提示几个潜在破环性提示如下:

  • VPD 运行的方式是重写查询以添加额外的谓词。 用户查询可能写得很好,可能调整得很好,但是引入额外的谓词却带来了破坏,因为优化计划可能改变。 您应该仔细考虑潜在的影响,通过建立索引降低风险。
  • 物化视图工作的方式是从底层表中选择行。 如果视图的模式所有者不受限制就可以访问该表,则只有那些和 VPD 策略一致的行才会被刷新,使视图不精确。
  • 如果您已经设置了复制,从事传播和接收工作的用户应该可以不受限制地对表进行访问。否则,他们只能复制表中的一部分。
  • 如果您使用直接路径插入(使用 APPEND 提示插入)对该表进行加载,那么您在该表上不可能有 VPD 策略。 使用可以不受限制地对表访问的用户,您应该临时禁止该策略,或进行插入。
  • 直接路径导出跳过 SQL 层;因此,VPD 策略不会被应用。 所以,当您使用 DIRECT=Y 选项导出表时,Oracle 忽略该表,并且使用常规路径导出该表。 这可能增加整个执行时间。

操作计划

这个计划是很复杂的,也是可改变的:

1. 识别 VPD 将保护的表。

2. 识别需要保护的表的列。

3. 识别限制条件,例如,Salaries > 1000。

4. 识别如何建立权限——例如,用户具备授权级别或角色吗?您可能希望将用户分为三组,每组都有相关的授权级别。 或者,可能您想根据角色对用户群的访问限制进行分配——经理可以访问所有的行,职员可以访问超过 SALARY > 2000 行,等等。

5. 决定您如何通过包变量、应用程序环境,或者静态表将权限传给策略函数。

6. 如果需要创建更多的索引,请进行识别。

7. 创建额外的索引。

8. 识别子表,决定一个方案来启动通过新列或 IN 条件对子表的限制。

9. 根据以上决定重新识别对索引的需求。

10. 创建索引。

11. 构建策略函数。

12. 创

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/178357/viewspace-910010/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    81
  • 访问量
    507776