安全保护项目: 一种分阶段的数据库基础架构保护方法 (第四阶段)

第 4 阶段

时间: 一个季度

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

这一部分内容包括:
·
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;

角色划分

数据安全中最有争议的问题之一是角色划分。 为了管理数据库,数据库管理员必须拥有某些权限,通常会赋予其 SYSDBA 角色,甚至是 DBA 角色。 然而,这一角色还有其它的一些权力:例如给别人授予权限,从任何表中选择所有数据。 该超用户权限与绝大多数法规相冲突,例如 Sarbanes-Oxley 和 GLBA,因为该权限允许个人拥有太多权力。

其实,DBA 角色是个与物理数据库相关的纯粹技术角色,一般情况下把它分配给一组用户。如果同样的人群也能够查看并更改任何用户数据,那么这种情况就会产生数据漏洞的严重潜在安全性风险。当数据库管理员可以删除任何数据,甚至审计线索时,责任可查性将成为问题。 然而,要实现合规性,需要明确划分职责和权限。因此,管理物理数据库的权限不应该包括查询或修改用户数据权。

传统上,Oracle 数据库不支持这种划分。 所以,在 2006 年 Oracle 宣布了两种革新性的工具(写这篇文章时它们都处于实验阶段)。 首先,Oracle Database Vault (Oracle 数据库 10g 第 2 个企业版的一个选项)通过创建权限“域”实现权限分离。 例如,DBA 不再有无限权利 查询和修改任何表。 相反,DBA 的权限将被限制到一个具体的权限范围,即权限域。 因此,Database Vault 抛弃能删除所有跟踪的万能超级用户的理念。相似地,独立产品 Oracle Audit Vault 提供了一个安全的审计工具,该工具自成一体,位于 DBA 或者应用程序管理人员控制区域外。只有安全管理员可以控制审计线索。可以使用这两种工具将这里的三种相关角色——管理物理数据库、管理对象权限、管理审计线索——完全分开。达到所有合规性规定的要求。

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 不同版本中引起不同的行为:
    • 在 Oracle9i 数据库中,处理器模块 以无提示的方式 停止对该行进行检索,不会报错。 因此,如果有 100 行,其中 4 行满足了审计条件,处理器模块运行四次,每次都会失败。 该查询将仅仅返回 96 行,而不报告任何错误,您将绝不会知道事情已经发生了。 很显然,这种做法会产生不精确的结果。
    • 在 Oracle Database 10g 第 1 版中,处理器模块将忽略处理器模块中的错误,按照预期检索所有 100 行。
    • 在 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) 是一个很大的主题,因此我在这里只将一些基本的。

假设您有一个称为 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. 创建策略(但是禁止)。
  13. 在某个轻松活动的一天里,启动该策略和测试,使用常规用户账户访问该表以确保该策略的运行。 如果该策略不运行,请检查跟踪文件以找到错误。
  14. 如果该策略不运行,请启动该策略。
  15. 监控性能。
  16. 识别更多需求以构建索引,使用大纲,等等。
  17. 迭代所有表。


4.3 屏蔽敏感的列

背景
把您自己想象成为一名业余数据库黑客。 这里的数据库包含医疗记录,您正在寻找的信息是诊断代码。 您将寻找哪些列? 可能是称为诊断、疾病或者类似的列。

正如您可以看到的,带有明显名字的敏感列是至关重要的安全问题。

策略
如果对手以前不了解您数据库的内容,并且这些列的名字不直观,他们将不会去解读列的含义。 这个策略称为“无名安全”。即使故意闯进数据库的经验丰富的黑客在做其它事情之前仍将需要追捕到列的名称。因为他们的时间可能有限——几乎一直都是这样——他们通常会转到下一个机会上。 当然,使用无名列也加大了开发的难度。

进行折衷还有其它的办法,然而: 通过列屏蔽,您可以隐藏列的内容,只有合法用户才可以看到列的内容。

列屏蔽的方法有两种: 使用视图和使用 VPD。

使用视图。 这种方法适用于 Oracle 任何版本,但是如果您的数据库版本是 Oracle9i 或者更早,就只能选择这种方法。

假设您的表和以下类似:

SQL> desc patient_diagnosis
Name                              Null?类型
 ------------------- ------ -------------
 PATIENT_ID                 NUMBER
 DIAGNOSIS_ID               NUMBER
 DIAGNOSIS_CODE             VARCHAR2(2)
 DOCTOR_ID                  NUMBER(2)
 BILLING_CODE               NUMBER(10)

行类和以下类似:

SQL> select * from patient_diagnosis;

PATIENT_ID DIAGNOSIS_ID DI  DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
         1            1 01          1         1003
         1            2 02          1         1003
         1            3 11          1         1003
         2            1 11          1         1005
         2            2 41          2         1005

在这里,您想屏蔽列 DIAGNOSIS_CODE 的值。

create view vw_patient_disgnosis
as
select
   patient_id,
   diagnosis_id,
   doctor_id,
   billing_code
from patient_diagnosis
/

然后,您可以给视图 VW_PATIENT_DIAGNOSIS 创建同义词 PATIENT_DIAGNOSIS,授予视图(而不是表)选择。 该视图屏蔽列 DIAGNOSIS_CODE。

这是一个相当简单的解决方案,因此您不要将所有用户的列屏蔽掉,您可能想创建基于角色的匿名——如果用户是一名经理,请显示被保护的列;否则的话不要显示。其方法是:传递应用程序环境或者全球变量以指定用户的角色。 如果应用程序环境属性是 IS_MANAGER,您可以使用:

create or replace view vw_patient_disgnosis
as
select
   patient_id,
   diagnosis_id,
   decode(
      sys_context('USER_ROLE_CTX','IS_MANAGER'), 
      'Y', DIAGNOSIS_CODE, null
   ) diagnosis_code,
   doctor_id,
   billing_code
from patient_diagnosis;

这是一个更加灵活的视图,该视图可以授权给所有的用户,该视图的内容会随着用户角色的不同而不同。

使用 VPD。 Oracle 数据库 10g 中引入的新特性使 VPD 更加有用: 创建视图是没有必要的。 相反,VPD 策略可能抑制显示。 这里,VPD 策略函数和以下类似:

  1  create or replace function pd_pol
  2  (
  3     p_schema        in varchar2,
  4     p_obj           in varchar2
  5  )
6  return varchar2
  7  is
  8     l_ret   varchar2(2000);
9  begin
 10     if (p_schema = USER) then
 11             l_ret := NULL;
 12     else
 13             l_ret := '1=2';
 14     end if;
 15     return l_ret;
16  end;

现在构建策略函数:

1  begin
  2     dbms_rls.add_policy (
  3         object_schema          => 'ARUP',
  4         object_name            => 'PATIENT_DIAGNOSIS',
  5         policy_name            => 'PD_POL',
  6         policy_function        => 'PD_POL',
  7         statement_types        => 'SELECT',
  8         update_check           => TRUE,
  9         sec_relevant_cols      => 'DIAGNOSIS_CODE',
 10         sec_relevant_cols_opt  => dbms_rls.all_rows
 11     );
12  end;

注意行号 9 和 10。在第 9 行中,我们提及将列 DIAGNOSIS_CODE 作为敏感列。在第 10 行中,我们指出如果选择了该列,VPD 显示所有列;但是该列值却显示为 NULL。 这就有效地屏蔽了该列。在策略函数中,请注意如果表的所有者进行选择,应用的谓词为 NULL。因此,VPD 限制就不被应用,列也不显示。

请记住,没有“更换”策略的方法。 如果旧策略还存在,您必须首先抛弃旧策略。

begin
    dbms_rls.drop_policy (
        object_schema      => 'ARUP',
        object_name        => 'PATIENT_DIAGNOSIS',
        policy_name        => 'PD_POL'
    );
end;

现在,您可以进行测试。

SQL> conn arup/arup
Connected.
SQL> select * from patient_diagnosis;

PATIENT_ID DIAGNOSIS_ID DI  DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
         1            1 01          1         1003
         1            2 02          1         1003
         1            3 11          1         1003
         2            1 11          1         1005
         2            2 41          2         1005

注意:DIAGNOSIS_CODE 列值显示出来了,因为 ARUP 是表的所有者,ARUP 应该看得到这些值。 现在,以对该表有选择权限的另一名用户身份进行连接,执行相同的查询。

SQL> set null ?
SQL> conn ananda/ananda
SQL> select * from arup.patient_diagnosis;

PATIENT_ID DIAGNOSIS_ID D  DOCTOR_ID BILLING_CODE
---------- ------------ - ---------- ------------
         1            1 ?          1         1003
         1            2 ?          1         1003
         1            3 ?          1         1003
         2            1 ?          1         1005
         2            2 ?          2         1005	 

注意列 DIAGNOSIS_CODE 是如何显示所有空值的。

除了不需要在表上创建视图,不需要创建同义词指向该视图,不需要维护额外的授权之外,该方法是更加优秀的。如果您需要拥有不同的策略把该值显示给不同的人,您可以很容易地修改策略函数(第 11 行)添加更多的检查。例如,您的策略可以是:所有用户都可以看到敏感性不强的诊断代码(例如普通感冒)。因此,您的策略函数和下面的类似,假设一般性感冒的 DIAGNOSIS_CODE 为“01”。

  1  create or replace function pd_pol
  2  (
  3     p_schema        in varchar2,
  4     p_obj           in varchar2
  5  )
6  return varchar2
  7  is
  8     l_ret   varchar2(2000);
9  begin
 10     if (p_schema = USER) then
 11             l_ret := NULL;
 12     else
 13             l_ret := 'diagnosis_code=''01''';
 14     end if;
 15     return l_ret;
16* end;

注意:仅当诊断代码为“01”而不是其它时,我们在第 13 行添加要显示的额外谓词。 现在进行测试。

SQL> conn arup/arup
Connected.
SQL> select * from arup.patient_diagnosis;

PATIENT_ID DIAGNOSIS_ID DI  DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
         1            1 01          1         1003
         1            2 02          1         1003
         1            3 11          1         1003
         2            1 11          1         1005
         2            2 41          2         1005

SQL> conn ananda/ananda
Connected.
SQL> select * from arup.patient_diagnosis;

PATIENT_ID DIAGNOSIS_ID DI  DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
         1            1 01          1         1003
         1            2 ?           1         1003
         1            3 ?           1         1003
         2            1 ?           1         1005
         2            2 ?           2         1005

注意:诊断代码“01”代表病人 id 1 和诊断 id 1,这是唯一允许的诊断代码;因此显示得很清晰。 其它的显示已经显示为孔,并且得到有效地屏蔽。

提示
如果您想屏蔽敏感列,程序也没有提及到它们,就没有提示。

如果您使用视图方法(这里敏感列只是从该视图中删除),则将会引发一个问题,这里程序使用像 SELECT * FROM TABLE ... 一样的结构。 因为已经没有明确对列进行命名,缺少一列将影响到程序执行。 但是,这不是一个关于修改视图方法(在这里列仍然存在但是为空)的问题。

有一个您应该意识到的很重要的提示。 假如您有一个称为“CONTRACT_AMOUNT”的列;如果数值小于某个特定值(比如 500),该列就显示。如果数值大于 500,该列就显示为空。 该表有三行,这三行所在列的数值分别为 300, 300, 600。在列屏蔽之前,如果用户提交以下查询

select avg (contract_amount) from contracts;

他将得到 400 (就是 300,300 和 600 的平均值)。 在列屏蔽之后,数值为 $600 的列的值将变为空,因此用户将看到的值分别为 300,300 和空。 现在,输入同样的查询,将会显示 200 (300,300 和空)。 请注意一个重要的区别: 所显示的值为 200;而不是 400

请意识到列屏蔽可能引入的这种重要区别。

操作计划

  1. 在所有敏感的表上列出所有敏感的列。
  2. 确定将要屏蔽的敏感的列。
  3. 确定权限模式。
  4. 如果您使用的是 Oracle 数据库 10g 第 1 版或更高版本,请选择 VPD 方法。
    另外,
    选择基于视图的方法。
  5. 如果您选择 VPD 方法:
    1. 给各个表构建策略函数。
    2. 给各个表构建策略。 这将帮助您在特定的表上对屏蔽进行控制。
  6. 如果您选择基于视图的方法:
    1. 在各个表(表的名字通常为 VW_<table_name>)上创建视图,
    2. 创建指向该视图的同义词(同义词的名称和表的名称相同)。
    3. 在表上撤消给用户授予的权限。
    4. 再次给视图授予权限。
    5. 重新编译所有依赖的无效对象。

 



4.4 对敏感的数据进行加密

背景
正如我前面提到的,安全就好比在寒冷的冬天里,您穿上好几件衣服或穿最庞大的冬天使用的夹克御寒。但是,构建各防御层可能阻止不了最坚决的恶意入侵者,当然这也不会总能够防御合法用户盗窃公司财产。这里的组最后一道防线是加密,通过加密,用户(或者恶意入侵者)只有使用密码才可以访问到数据。 没有密码的数据是无效的。如果您保护了密码,您就保护了数据。

请记住,加密不能替代其它层次的安全性。 不管怎样,您必须有那些防御。

而且,加密是一个很大的课题,但是我将在这里给您一个可引发操作的概述。

Oracle 提供两种加密方式:

  1. 加密 API 例如包 dbms_obfuscation_toolkit 和 dbms_crypto (在 Oracle 数据库 10g 第 1 版和更高版本中)。 使用这些包,您可以构建您自己的基础架构,对数据进行加密。 这种方法的灵活性最强,但是构建和管理却相当复杂。

  2. 透明的数据加密是 Oracle 数据库 10g 第 2 版和更高版本的一个特性;使用该特性后,您就不必手动进行密码管理了。 数据库管理密码,但是正如名称所指,加密是透明的——数据仅仅以加密的方式存储而已。 当您选择了这种方式,就会明白的。

我建议在您阅读策略部分之前,请分别察看 Oracle 文档(Oracle 数据库安全指南的 第 17 章 和 Oracle 数据库高级安全管理员指南的 第 3 章)。

策略
选择常规加密,还是透明的数据加密是很重要的。 (然而,在 Oracle 数据库 10g 第 2 版之前, 您只能选择常规加密。)

  • 不论哪种方式,您都必须识别要加密的表,尤其是要加密的列。 因为例行加密毁坏 CPU 周期,所以对所有列进行加密可能并不好。
  • 下一步是选择加密算法。 通常是选择 156 位加密的三重数据加密标准 (DES3)。 然而,以 Oracle 数据库 10g 第 1 版开始,您可以访问更新、更快和更安全的高级加密标准 (AES) 算法,使用该算法要有 128 位密码。
  • Oracle9i 数据库提供 dbms_obfuscation_toolkit;您可以使用 Oracle 数据库 10g 第 1 版访问一个更好的工具 dbms_crypto。 您仍然可用更老的包,但是如果您第一次构建加密基础架构,请不要使用。
  • 在这一点,您必须选择 TDE 或您自己的例行使用的(如果可以应用的话)。 下表可以帮助您作出决定。
 透明的数据加密用户构建的加密

灵活性

最小 — 例如,如果 SALARIES 表中的 SALARY 列加密了,那么 任何 能够对该表进行访问的用户都将能够清晰地察看数据。 您不能按照角色和级别对那个列进行有选择性的控制。 该数据库中的数据可以加密,但是用户访问时要能解密。

强健 — 例如,只有 用户为经理时,您才可以定义以明文方式显示列;否则进行加密。 这将确保不同的用户使用同样的应用程序察看不同的数据。 这种灵活性也可以扩展到其它变量,例如访问数据库的时间和客户机器。

设置

最小 — 该工具的确是透明的 — 您只需执行该命令(假定所有一次性的工作都已经完成,例如创建钱夹):

ALTER TABLE SALARIES MODIFY (SALARY ENCRYPT)

广泛的 — 要向用户提供无缝的界面,您必须创建对列进行解密的视图。 接着应该对该视图进行授权。 在管理上这添加了复杂性。

密码管理

自动化—该数据库使用钱夹处理密码管理。

人工—因为您必须管理密码,所以您必须决定如何平衡两种相互冲突的需求:

  • 确保密码的安全,恶意入侵者无法获取该密码。
  • 应用程序可以访问密码。

对列的限制

一些—某些列不能加密,例如有些列有分区密钥、数据类型 BLOB,等等,这样的列不能加密。

仅仅限制为 LONG。

对索引的支持

N/A—因为数据是以加密的方式存储的,所以在查询中索引不可能发挥作用。

支持—因为您控制了加密,所以您创建替代列构建索引。

如果您决定使用 TDE,请采取以下步骤:

  1. 配置钱夹: 钱夹一般位于文件夹 $ORACLE_BASE/admin/$ORACLE_SID/wallet 中,但是您可以通过将以下行放入文件 SQLNET.ORA 中使用任何位置:
    ENCRYPTION_WALLET_LOCATION=
     (SOURCE=
        (METHOD=file)
        (METHOD_DATA=
           (DIRECTORY=/orawall)     )  ) 
    

    在这里,将钱夹位置设置为 /orawall。

  2. 打开该钱夹,分配一个密码: 执行以下命令:
    alter system set encryption key authenticated by "53cr3t";
  3. 选择的密码要难以猜测,容易记忆。 (为了安全,您可能不想让 DBA 了解钱夹密码,所以需要另一个人打开该钱夹。) 现在,从现在开始,每次数据库打开时,您必须使用以下方式打开该钱夹:
    alter system set encryption wallet open authenticated by "53cr3t";

     

之后,您创建的表可以包含经过加密的列:

create table accounts
(
acc_no       number       not null,
first_name   varchar2(30) not null,
last_name    varchar2(30) not null,
SSN          varchar2(9)             ENCRYPT USING 'AES128',
acc_type     varchar2(1)  not null,
folio_id     number                  ENCRYPT USING 'AES128',
sub_acc_type varchar2(30),
acc_open_dt  date         not null,
acc_mod_dt   date,
acc_mgr_id   number
)

当用户将数据插进该表时,数据就自动转化为加密的数据并放置到磁盘上。 类似地,当选择语句检索到数据时,数据自动转化为加密的值,并且向用户显示。

提示
和任何重要的更改一样,有一些重要的提示。

  • 加密是非常占用 CPU 的操作。 如果系统已经受 CPU 所限,这会使系统更糟。
  • 索引不会和加密的列配合得很好,尤其是谓词,比如 WHERE <ColumnName> LIKE 'XYZ%'。该谓词应该已经在未加密的列中使用索引范围扫描,但是还将使用全面的表扫描。
  • 密码管理是一个很重要的问题。 如果您丢失了密码,就访问不到该数据。

操作计划
操作计划位于策略部分。

 



4.5 安全备份

背景
许多情况下,DBA 会忽略最容易受到攻击的要害: 数据库备份。 一旦数据不在服务器的安全范围内,您将不再能控制这些数据。 如果恶意入侵者可以盗窃磁带,他就可以将它们安装到一个不同的服务器上,恢复数据库,再慢慢地浏览数据。

幸运地是,即使这样您只要使用加密备份还是可以消除这种风险的。

策略
在 Oracle 数据库 10g 第 2 版和更高版本中,您可以以三种不同的模型在 RMAN 上对备份进行加密: 透明模式、基于密码的模式和混合模式。

透明模式。 按照这种方法(也是最常用的方法),RMAN 从加密钱夹中获取加密密码(在前面讨论过了),并使用它对备份集进行加密。 不必说,在备份和恢复中钱夹必须是打开的。 如果钱夹没有打开,您将看到以下错误:

ORA-19914: unable to encrypt backup
ORA-28365: wallet is not open
  1. 执行以下命令打开钱夹:
    alter system set encryption wallet open authenticated by "53cr3t";

    当然,可以设置不同于 "53cr3t" 密码。 请记住,这是区分大小写的,因此必须带有双引号。

  2. 确保启动整个数据库的加密。 您可以执行以下命令启动加密:
    RMAN> configure encryption for database on;
  3. 另外,如果您想对几个表空间进行加密,您可以为所有的表空间执行以下命令。
    RMAN> configure encryption for tablespace users on;
  4. 之后,您可以使用常规的备份命令而无需其他用户的干预。
    RMAN> backup tablespace users;
  5. 当您恢复该备份时,该钱夹必须是打开的。 如果钱夹没有打开,恢复备份时您将看到以下错误:
    RMAN> restore tablespace users;
    
    Starting restore at 26-MAY-05
    using channel ORA_DISK_1
    
    ... messages ...
    ORA-19870: error reading backup piece C:/ORACLE/PRODUCT/10.2.0/FLASH_RECOVERY_AR
    EA/ANANDA/BACKUPSET/2006_02_09/O1_MF_NNNDF_TAG20060209T221325_1YR16QLT_.BKP
    ORA-19913: unable to decrypt backup
    ORA-28365: wallet is not open  
    

    错误信息是很清楚的;该钱夹必须是打开的。 如果您需要在其它服务器上恢复表空间,您必须拷贝该钱夹,使用正确的密码打开该钱夹。 如何恶意入侵者盗窃了磁带,他将不能恢复备份。

基于密码的模式。 这种情况下,不需要将钱夹用于密码管理。 密码加密备份,同时密码本身也使用密码加密。 命令如下:

RMAN> set encryption on identified by "53cr3t" only;
RMAN> backup tablespace users;

密码将对上面产生的备份集进行加密。 为了在恢复中对密码进行加密,您必须使用如下密码:

RMAN> set decryption identified by "53cr3t ";
RMAN> restore tablespace users;

这种方法就不需要使用钱夹了。 因此在任何服务器上恢复备份,您只需要密码,不再需要钱夹。 然而,您的密码在脚本中必须是可见的。这样,任何能访问数据库服务器的恶意入侵者将能够读取该密码。 请参阅第 2 阶段,其中涉及了如何隐藏密码的内容。

混合模式。由名称可知,该模式两种方法的结合体。 您按照以下方式进行备份:

RMAN> set encryption on identified by "53cr3t";
RMAN> backup tablespace users;

注意:在命令 set encryption 中没有“only”语句。 这样就可以使用两种方法之一来恢复备份: 使用密码“tiger”,或者打开钱包。 例如,请注意以下命令。 没有提供密码,但是成功地进行了恢复。

RMAN> sql 'alter tablespace users offline';
RMAN> restore tablespace users;

Starting restore at 26-MAY-05
allocated channel:ORA_DISK_1
... restore command output comes here ...

当您使用脚本处理备份时,经常不得不将数据库恢复到不同的服务器(例如 QA 服务器)上时,这种方法将派上大用场。 但是一般来说,这种方法通常没有太大的实际用处。

如果您使用透明模式进行备份加密,您也可以备份钱夹。 即使对手获得了钱夹,他没有密码也打不开钱夹。

问题

  • 我以前提到加密是非常占用 CPU 的过程。因此,对整个 RMAN 备份集进行加密将是高度占用 CPU 的操作。 您可以通过部分地对备份进行加密缩短 CPU 周期——仅仅选择包含敏感数据的表空间。 一个更好的方法是将透明数据加密用于列级加密。
  • 透明方法中的钱夹和基于密码方法的密码是很重要的。 如果您将它们都丢失了,您将不再能对备份进行加密;因此,要有一个计划对它们进行备份。
  • 如果您使用基于密码的加密,该密码必须在脚本中。 但是可能很容易被盗。

操作计划

  1. 确定您是否真的需要对整个备份集进行加密,而不是对某些表中的某些列加密。
  2. 如果对 RMAN 备份进行加密,请选择整个数据库或特定表空间。
  3. 选择基于密码的方法、透明方法,以及混合模式方法。
  4. 如果采用透明方法,或混合模式方法,则
    1. 配置钱夹。
    2. 打开钱夹。
    3. 在 RMAN 中,配置表空间或者整个数据库进行备份加密。
  5. 如果是基于密码的方法,或者混合模式方法,则
    1. 选择密码,并将它放入 RMAN 脚本中。 使用第 2 阶段中说明的任一密码隐藏技术。
    2. 只使用那些脚本进行备份。

 


4.6 从存档日志中挖掘历史

背景
数据库安全实施的一个很重要的方面是确保数据库上不发生未授权的 DDL 活动。 恶意入侵者获取连接数据库的合法路由后,可以很方便的写几段代码来对数据库实施简单的拒绝服务攻击。

在第 3 阶段中,您了解了如何保护主要对象,所以没有 DBA 的同意是不能更改主要对象的。 但是,如果非法更改得到同意,但在后来才得知发生了攻击,该怎么办呢? 这就要用到安全的第四个方面——责任可查性。

一个选项是开启 DDL 审计以跟踪 DDL 活动。 总而言之,这是最容易的方法——易于设置,更易于浏览,可以进行归档,等等。 然而,审计会影响性能,这是我们正试图避免的。 问题是如何重新跟踪 DDL 语句,而不用对审计进行设置。

策略
可以使用称为 Log Miner 的工具(或特性)。 Oracle8i 数据库中推出了 Log Miner,利用它可以搜索在线重做日志或者归档日志。

下文告诉您如何设置日志挖掘以挖掘 DDL 详细信息。 首先,获取要挖掘的在线日志文件或者归档日志文件,并将它们添加到 Log Miner 会话中。

sqlplus / as sysdba

begin
   dbms_logmnr.add_logfile (
           'C:/ORACLE/DATABASE/ANANDA/REDO03.LOG');
   dbms_logmnr.add_logfile (
           'C:/ORACLE/DATABASE/ANANDA/REDO02.LOG');
   dbms_logmnr.add_logfile (
           'C:/ORACLE/DATABASE/ANANDA/REDO01.LOG');
end;
/

添加文件之后,启动 Log Miner 会话。 您必须传递数据字典源;在这里我们已经将在线类别指定为源。

begin
   dbms_logmnr.start_logmnr (
      options => dbms_logmnr.dict_from_online_catalog
   );
end;

被挖掘的内容放在称为 V$LOGMNR_CONTENTS 的视图中;但是该视图是临时的——仅仅启动 Log Miner 的会话可以看到该视图。 因此,如果以后您想进行分析,您需要将它保存在永久表中。

create table lm_contents
nologging
as
select * from v$logmnr_contents;

Now for the analysis. To find the DDL commands you would issue the following query:

select sql_redo
from lm_contents
where operation = 'DDL'
and seg_owner not in ('SYS','SYSTEM','PUBLIC');

下面是一个样例输出: 注意:没有 DROP TABLE 语句——在 Oracle 数据库 10g中,删除的表实际上没有被删除,而是进行了重新命名。 SQL_REDO 将反映这点。 实际上,用户使用 PURGE 子句删除表时,列 SQL_REDO 将会反映正确的命令。 为了保存空间,我已经修剪了输出,所以函数和过程的 DDL 出现了一部分。 我也已经使用 RECSEPCHAR '.'以显示多行记录中的设计行。)

SQL_REDO
-------------------------------------------------------------------------------

ALTER PACKAGE "XDB"."DBMS_XSLPROCESSOR" COMPILE SPECIFICATION REUSE SETTINGS;
ALTER PACKAGE "XDB"."DBMS_XMLDOM" COMPILE SPECIFICATION REUSE SETTINGS;
ALTER PACKAGE "XDB"."DBMS_XMLPARSER" COMPILE SPECIFICATION REUSE SETTINGS;
ALTER PACKAGE "EXFSYS"."DBMS_RLMGR_DR" COMPILE BODY REUSE SETTINGS;
truncate
table developers;
...............................................................................
create table patient_diagnosis
(
        patient_id      number,
...............................................................................
create view vw_patient_diagnosis
as
...............................................................................
create or replace view vw_patient_diagnosis
as
...............................................................................
create or replace function pd_pol
(
p_schema in varchar2,
...............................................................................
create or replace function pd_pol
(
p_schema in varchar2,
...............................................................................
create or replace function pd_pol
(
p_schema in varchar2,
...............................................................................
grant connect, resource to ananda identified by  VALUES '1DB10D95DE84E304' ;
create or replace function pd_pol
(
...............................................................................
create or replace function pd_pol
(
p_schema in varchar2,
...............................................................................
ALTER TABLE "ARUP"."TEST1" RENAME TO "BIN$JQHaX2mpSxOyrhkxAteHmg==$0" ;
drop table test1 AS "BIN$JQHaX2mpSxOyrhkxAteHmg==$0" ;

当然,该输出本身可能是没有任何意义;您必须察看更多的信息,例如 Log Miner 条目中的时间戳记、SCN、等等,在用户操作和实际事件之间进行有效的连接。

select timestamp, scn, seg_owner, seg_name
from lm_contents
where operation = 'DDL'
and seg_owner not in ('SYS','SYSTEM','PUBLIC')
/

下面是一个样例输出:

TIMESTAMP        SCN SEG_OWNER  SEG_NAME
--------- ---------- ---------- ------------------------------
06-FEB-06    1024674 XDB        DBMS_XSLPROCESSOR
06-FEB-06    1026884 XDB        DBMS_XMLDOM
06-FEB-06    1026896 XDB        DBMS_XMLPARSER
06-FEB-06    1026918 EXFSYS     DBMS_RLMGR_DR
06-FEB-06    1029244 ARUP       DEVELOPERS
08-FEB-06    1096847 ARUP       PATIENT_DIAGNOSIS
08-FEB-06    1097057 ARUP       VW_PATIENT_DIAGNOSIS
08-FEB-06    1097920 ARUP       VW_PATIENT_DIAGNOSIS
08-FEB-06    1100059 ARUP       PD_POL
08-FEB-06    1100157 ARUP       PD_POL
08-FEB-06    1100386 ARUP       PD_POL
08-FEB-06    1100413 ANANDA
08-FEB-06    1101544 ANANDA     PD_POL
08-FEB-06    1101564 ARUP       PD_POL
09-FEB-06    1123950 ARUP       TEST1
09-FEB-06    1123953 ARUP       TEST1

注意:我使用的是 SEG_OWNER,不是 USERNAME。 由于 Oracle 数据库 10.2.0.1 中的一个缺陷没有解决,USERNAME 没有放入进去。

这只是怎样从归档日志中抽取 DDL 语句的一个示例。 您也可以使用任何语句挖掘日志——DML。 DML 语句挖掘是对审计的重要代替,因为它们对数据库不施加任何性能压力。

提示
Log Miner 是非侵入的,但是在服务器上它不占用很多 CPU 周期和 PGA 内存。 因此,请仔细地操作 Log Miner,最好在减少装载的条件下操作。 (另外一个选项是将存档日志移动到不同的服务器上,在那些挖掘存档日志。只要有可能的时候,都应该利用该选项。)

操作计划

  1. 识别您想从日志中挖掘的语句,以及挖掘频率。 一些示例可能是与删除对象有关的 DDL 语句;但是您可能需要更加有选择性。 在数据仓库环境里,应用程序暂时创建许多表,然后删除这些表,因此您可能想不选择那些模式。
  2. 使用以上技术定期从归档日志中提取信息,并因为可能的滥用和模式对它们进行分析。


4.7 结论

该阶段的任务量比较少,但是这些任务执行起来却要花费很多时间。 另外,因为它们是目标的一部分,所有没有明晰的详细信息。 这些次要的细节变化很大,所以要进行综合的通用型描述是不可能的。

安全要求的最重要因素是要明白您不可能在真空中求得安全。为了有效地构建一个安全的数据库基础架构,您的行为必须和对机构独特本质的理解协调起来,您的分析必须包括业务流程,从而将敏感数据和非敏感数据隔离开来。 例如,信用卡数在任何机构都将被保护,但是销售数怎么办呢?在某些机构中(例如零售店),数据量相当庞大,加密保护就不适宜了。但是对冲基金商贸公司却是可行的, 在这里销售数据被严加保护。查看敏感数据的一个分层方法可能实用于某些情况下;但是在大多数情况下,分层方法最可能按需提供。

即将结束时,我希望您已经学习到某些您现在就可以使用的有价值的工具和技巧来保护您的数据库基础架构。 如果您能花费一些时间让我了解您对第 4 阶段的反馈和改进建议,同时提供其它相关问题和资料,我将非常感谢。

 

 

这里提供的内容仅仅是为了教学,并没有得到 Oracle 的确认;使用这些内容后的结果自负。 无论如何您都不应该将这里提供的内容视为咨询或服务产品的一部分。

参阅项目锁定 TOC 和安全入门指南 

 

 

http://www.oracle.com/technology/global/cn/pub/articles/project_lockdown/phase4.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值