Oracle Database 12c Security - 10. Oracle Database Vault

Database Vault,简称DBV,2005年发布。

HISTORY OF PRIVILEGED ACCOUNTS

Oracle数据库中的SYS用户相当于Linux中的root用户。另一个有DBA权限的用户是SYSTEM。

Separation of duty (SoD),拥有所有权限会导致做坏事,甚至可以删除审计记录。后者可使用外部审计。也就是说,虽不能防止其行为,但可记录其痕迹。

SYS as SYSDBA (Super User 0)

尽管我们可以使用SYS登录,但SYS实际是schema, 拥有很多对象。

  • 我们需要SYS来报错核心数据库对象;需要以SYS登录安装patch,升级。
  • SYS用户必须控制,不能跳过安全检查

SECURITY SHOULD HAVES

Multifactored Security

多因子认证只用多余1中方式认证用户。

Conditional Security

Context-based security - 根据上下文确定是否赋权
Adaptive security - 即时调整和改变
Separation of Duty (SoD) - 禁止让一个人执行所有操作
Conditional auditing - 细粒度的审计

DBV COMPONENTS

DBV嵌入到数据库软件的核心,是声明式的。

DVSYS拥有的一组表。DBMS_MACADM或OEMCC配置。

HAP = High Assurance Principle
HAP for database security = 1 DB mechanism + 1 DBV mechanism

DB mechanism指传统的账户,权限,角色等;DBV mechanism指factor,rule,realm和command rule。

Factors

factor是用PL/SQL来解析的。

Rules

factor的组合(与,或)就是rule。
rule set是rule的库,便于维护和重用。

Realms

Realm是为需要保护的对象建立的域,系统权限无法访问。可认为是安全沙箱。

12c后的relam称为mandatory realm,即使是对象的属主和具有对象直接访问权限也受realm的保护。

realm可关联用户和角色,用户可以是管理者或参与者。

Command Rules

基于上下文和rule的安全检查。
和SAR(Secure Application Role)激活角色不同,用户必须具有访问对象的权限,Command Rule是额外的保护。

Access = Privilege + DBV rule.

CONFIGURING AND ENABLING DBV

DBV依赖OLS,因此启用DBV会自动启用OLS,但无需OLS许可,除非单独使用OLS。

12c中,DBV和OLS一样默认已安装。

SQL> select parameter, value from v$option where parameter like '%Vault%';
PARAMETER                      VALUE
------------------------------ ----------
Oracle Database Vault          FALSE

DBV Administration Using Common Accounts

启用DBV需要先在CDB中操作:

GRANT CREATE SESSION, SET CONTAINER TO c##sec_admin_owen 
  IDENTIFIED BY password CONTAINER = ALL;
GRANT CREATE SESSION, SET CONTAINER TO c##dbv_owner_root_backup 
  IDENTIFIED BY password CONTAINER = ALL;
GRANT CREATE SESSION, SET CONTAINER TO c##accts_admin_ace 
  IDENTIFIED BY password CONTAINER = ALL;
GRANT CREATE SESSION, SET CONTAINER TO c##dbv_acctmgr_root_backup 
  IDENTIFIED BY password CONTAINER = ALL;

connect sys as sysdba

BEGIN
 CONFIGURE_DV (
   dvowner_uname         => 'c##dbv_owner_root_backup',
   dvacctmgr_uname       => 'c##dbv_acctmgr_root_backup',
   force_local_dvowner   => FALSE);
 END;
/

@?/rdbms/admin/utlrp.sql

CONNECT c##dbv_owner_root_backup

EXEC DBMS_MACADM.ENABLE_DV;

CONNECT / AS SYSDBA

SHUTDOWN IMMEDIATE
STARTUP

至此,启用完毕。以上两个backup结尾的用户平时不用,是用来给实际的DV Owner和Account Manager赋权的:

CONNECT c##dbv_owner_root_backup

GRANT DV_OWNER TO c##sec_admin_owen WITH ADMIN OPTION;

CONNECT c##dbv_acctmgr_root_backup

GRANT DV_ACCTMGR TO c##accts_admin_ace WITH ADMIN OPTION;

确认DBV已启用:

SELECT * FROM SYS.DBA_DV_STATUS;
NAME                STATUS
------------------- --------------------
DV_APP_PROTECTION   NOT CONFIGURED
DV_CONFIGURE_STATUS TRUE
DV_ENABLE_STATUS    TRUE

此时,PDB中的DBV尚未启用。

connect sys@sales
BEGIN
 CONFIGURE_DV (
   dvowner_uname         => 'c##dbv_owner_root_backup',
   dvacctmgr_uname       => 'c##dbv_acctmgr_root_backup');
 END;
/

@?/rdbms/admin/utlrp.sql

CONNECT c##dbv_owner_root_backup@sales

EXEC DBMS_MACADM.ENABLE_DV;

connect / as sysdba
ALTER PLUGGABLE DATABASE sales CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE sales OPEN;

SELECT * FROM DBA_DV_STATUS;
NAME                STATUS
------------------- --------------------
DV_APP_PROTECTION   NOT CONFIGURED
DV_CONFIGURE_STATUS TRUE
DV_ENABLE_STATUS    TRUE

CONNECT c##dbv_owner_root_backup@sales

GRANT DV_OWNER TO c##sec_admin_owen WITH ADMIN OPTION;

CONNECT c##dbv_acctmgr_root_backup@sales

GRANT DV_ACCTMGR TO c##accts_admin_ace WITH ADMIN OPTION;

至此,我们配置了common user来管理DBV,当然也可以用local user, 此略。

DBV Administration Using Delegated Accounts

指的就是使用local user来管理。Oracle Docs中介绍很详细,此略,就是将DV_OWNER和DV_ACCTMGR赋予local user。

Manually Configuring DBV in a PDB

前面演示过了。

MANAGING DBV CONFIGURATION

DBV Administration PL/SQL Package and Configuration Views

可用OEMCC或DVSYS.DBMS_MACADM Package。

connect c##sec_admin_owen/password@sales
desc DBMS_MACADM

DBV SECURITY POLICIES IN ACTION

ward off - 避开
一些Oracle Apps, 都有配置好了的安全策略,参见Master Note for Oracle Database Vault security policies with Siebel, PeopleSoft, JD Edwards EnterpriseOne and WebCenter Content (Doc ID 1623425.1)。

Installed DBV Roles

包括DV_SECANALYST,DV_ADMIN,DV_OWNER,DV_AUDIT_CLEANUP,DV_MONITOR,DV_ACCTMGR等。

其中最重要的:

  • DV_OWNER: 被赋予DV_ADMIN权限,并可以赋予他人DV_SECANALYST, DV_ADMIN, DV_OWNER权限。
  • DV_ACCTMGR:可CREATE, ALTER, DROP数据库账户

SoD with Roles, Realms, and Command Rules

根据SoD原则,数据库相关操作分为以下三类:

  • Database Account Administrator (DAA)
  • Operational Database Administrator (ODBA)
  • Security Administrator (SA)

DAA对应的是DV_ACCTMGR和CONNECT角色,对应用户c##accts_admin_ace。

可以看到,sys用户已经没有新建用户的权利:

SQL> alter session set container=sales;

Session altered.

SQL> grant create session to lisa identified by welcome1;
grant create session to lisa identified by welcome1
*
ERROR at line 1:
ORA-01031: insufficient privileges

关闭audit也是无权限的:

SQL>  ALTER system SET audit_sys_operations=false scope=spfile;
 ALTER system SET audit_sys_operations=false scope=spfile
*
ERROR at line 1:
ORA-01031: insufficient privileges

ODBA对应的用户默认是SYS,可用于赋权,管理PDB,备份等。

DBV将Package,数据,配置存于账户DVSYS。DVSYS.DBMS_MACADM是管理DBV的唯一手段。SA对应的即DV_OWNER 角色。

sys用户并不能给自己赋dv_owner权限:

SQL> show user
USER is "SYS"
SQL> grant dv_owner to sys;
grant dv_owner to sys
*
ERROR at line 1:
ORA-47410: Realm violation for GRANT on DV_OWNER

Default Audit Policies

由默认的审计策略,记录登录、赋权、账户操作等。

General Database Maintenance and Operations Authorizations

需使用DBMS_MACADM package AUTHORIZE% API。

Creating Custom DBV Policies

本例由HR和SH两个schema,使用的是Sample Schema。

创建两个realm,并将HR, SH中的对象添加到相应的realm。

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.create_realm(
          realm_name    => 'Sales History'
        , description   => 'Realm for protection of SH objects and roles'
        , enabled       =>  dbms_macutl.g_yes
        , audit_options =>  dbms_macutl.g_realm_audit_fail
        , realm_type    =>  0 );
END;
/
BEGIN
    dbms_macadm.create_realm(
          realm_name    => 'Human Resources'
        , description   => 'Realm for protection of HR objects and roles'
        , enabled       =>  dbms_macutl.g_yes
        , audit_options =>  dbms_macutl.g_realm_audit_fail
        , realm_type    =>  1 );
END;
/

BEGIN
    dbms_macadm.add_object_to_realm (
        realm_name    => 'Sales History'
      , object_owner  => 'SH'
      , object_type   => '%'
      , object_name   => '%');
END;
/
BEGIN
    dbms_macadm.add_object_to_realm (
        realm_name    => 'Human Resources'
      , object_owner  => 'HR'
      , object_type   => 'TABLE'
      , object_name   => '%');
END;
/

注意,这两个realm的类型,一个是普通的(0),一个是强制的(1)。

column name format a60
SELECT name, realm_type
FROM dvsys.dba_dv_realm
    ORDER BY name;

NAME                                                         REALM_TYP
------------------------------------------------------------ ---------
Database Vault Account Management                            REGULAR
Human Resources                                              MANDATORY
Oracle Database Vault                                        REGULAR
Oracle Default Component Protection Realm                    REGULAR
Oracle Default Schema Protection Realm                       REGULAR
Oracle Enterprise Manager                                    REGULAR
Oracle System Privilege and Role Management Realm            REGULAR
Sales History                                                REGULAR

8 rows selected.

简单来说,强制realm剥夺了SYS用户甚至是对象属主的权限,除非进行Realm authorization,参见这里:

SQL> connect hr/oracle@sales
Connected.
SQL> select count(*) from employees;
select count(*) from employees
                     *
ERROR at line 1:
ORA-01031: insufficient privileges

SQL> connect sys@sales as sysdba
Enter password:
Connected.
SQL> select count(*) from hr.employees;
select count(*) from hr.employees
                        *
ERROR at line 1:
ORA-01031: insufficient privileges

而对于不同realm:

SQL> connect sh/oracle@sales
Connected.
SQL> select count(*) from sh.sales;

  COUNT(*)
----------
    918843

SQL> connect system/Welcome1@sales
Connected.
SQL> select count(*) from sh.sales;
select count(*) from sh.sales
                        *
ERROR at line 1:
ORA-01031: insufficient privileges

接下来做Realm authorization, 将object owner指定为realm owner:

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.add_auth_to_realm (
      realm_name    =>'Human Resources'
    , grantee       => 'HR'
    , rule_set_name => NULL
    , auth_options  => dbms_macutl.g_realm_auth_owner );
END;
/

BEGIN
    dbms_macadm.add_auth_to_realm (
      realm_name    =>'Sales History'
    , grantee       => 'SH'
    , rule_set_name => NULL
    , auth_options  => dbms_macutl.g_realm_auth_owner );
END;
/

在以上语句中,grantee可以是用户或角色,建议角色。另rule_set_name为空,但也可配置以指定何时和如何进行Realm authorization。

现在hr可以访问自己的表了:

SQL> connect hr/oracle@sales
Connected.
SQL> select count(*) from hr.employees;

  COUNT(*)
----------
       107

接下来创建factor:

connect c##sec_admin_owen/password@sales

-- Create a factor for the day of the week
BEGIN
  dbms_macadm.create_factor(
        factor_name   => 'CURRENT_DAY',
        factor_type_name => 'Time',
        description   => 'The current day of the week',
        rule_set_name => NULL ,
        get_expr      => 'TO_CHAR(SYSDATE,''DY'')',
        validate_expr => NULL,
        identify_by   => dbms_macutl.g_identify_by_method,
        labeled_by    => dbms_macutl.g_labeled_by_self,
        eval_options  => dbms_macutl.g_eval_on_access,
        audit_options => dbms_macutl.g_audit_on_get_error,
        fail_options  => dbms_macutl.g_fail_with_message);
END;
/
-- Create a factor for the hour of the day
BEGIN
  dbms_macadm.create_factor(
        factor_name   => 'CURRENT_HOUR',
        factor_type_name => 'Time',
        description   => 'The current hour of the day',
        rule_set_name => NULL ,
        get_expr      => 'TO_CHAR(SYSDATE,''HH24'')',
        validate_expr => NULL,
        identify_by   => dbms_macutl.g_identify_by_method,
        labeled_by    => dbms_macutl.g_labeled_by_self,
        eval_options  => dbms_macutl.g_eval_on_access,
        audit_options => dbms_macutl.g_audit_on_get_error,
        fail_options  => dbms_macutl.g_fail_with_message);
END;
/
COMMIT;

在以上语句中,get_exp使用了SQL语句,也可以是PL/SQL函数,但返回必须是VARCHAR2类型。
例如:

SQL> connect sys/Welcome1@sales as sysdba
Connected.
CREATE OR REPLACE FUNCTION inside_maint_window RETURN VARCHAR2 IS
  l_now DATE := SYSDATE;
  l_hour NUMBER := TO_CHAR(SYSDATE,'HH24');
BEGIN
  IF TO_CHAR(l_now,'DY') = 'FRI'
     AND l_hour BETWEEN 19 AND 23 THEN
     RETURN 'Y';
  ELSE
     RETURN 'N';
  END IF;
END;
 12  /

Function created.

SQL> GRANT EXECUTE ON inside_maint_window TO dvsys;

Grant succeeded.

SQL> connect c##sec_admin_owen/password@sales
Connected.
BEGIN
  dbms_macadm.create_factor(
        factor_name   => 'In_Maintenance_Window',
        factor_type_name => 'Time',
        description   =>
           'The current system time is within the weekly maintenance window.',
        rule_set_name => NULL ,
        get_expr      => 'sec_pol.inside_maint_window',
        validate_expr => NULL,
        identify_by   => dbms_macutl.g_identify_by_method,
        labeled_by    => dbms_macutl.g_labeled_by_self,
        eval_options  => dbms_macutl.g_eval_on_access,
        audit_options => dbms_macutl.g_audit_on_get_error,
        fail_options  => dbms_macutl.g_fail_with_message);
END;
 16  /

PL/SQL procedure successfully completed.

查询factor:

CONNECT sh@sales
column DAY_OF_WEEK format a20
column HOUR_OF_DAY format a20

SELECT get_factor('CURRENT_DAY') DAY_OF_WEEK
, DVF.F$CURRENT_HOUR HOUR_OF_DAY
FROM dual;

DAY_OF_WEEK          HOUR_OF_DAY
-------------------- --------------------
WED                  16

Creating Rules and Rule Sets

rule返回bool值。rule应尽量重用。
DBV rule可关联多个rule set。rule set是rule的集合,其中所有的rule必须返回true。

先创建两个rule:

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.create_rule(
        rule_name => 'Is Maintenance Day of Week'
       , rule_expr => 'GET_FACTOR(''Current_Day'') = ''FRI'''
    );
END;
/
BEGIN
    dbms_macadm.create_rule(
        rule_name => 'Within Maintenance Hours'
       , rule_expr => 'TO_NUMBER(GET_FACTOR(''Current_HOUR'')) BETWEEN 19 AND 23'
    );
END;
/

然后创建rule set,管理的rule必须全部返回true:

-- Create the Maintenance Window DBV Rule Set
-- requiring all rules to be true
BEGIN
    dbms_macadm.create_rule_set(
        rule_set_name =>'Inside Maintenance Window',
        description =>'Checks to see if maintenance and patch activity can be executed.',
        enabled =>dbms_macutl.g_yes,
        eval_options =>dbms_macutl.g_ruleset_eval_all,
        audit_options =>dbms_macutl.g_ruleset_audit_fail,
        fail_options =>dbms_macutl.g_ruleset_fail_show,
        fail_message =>NULL,
        fail_code =>NULL,
        handler_options =>dbms_macutl.g_ruleset_handler_off,
        handler =>NULL);
END;
/
-- Associate the DBV Rules to the DBV Rule Set
BEGIN
   dbms_macadm.add_rule_to_rule_set (
     rule_set_name => 'Inside Maintenance Window'
   , rule_name     => 'Is Maintenance Day of Week'
   );
END;
/
BEGIN
   dbms_macadm.add_rule_to_rule_set (
     rule_set_name => 'Inside Maintenance Window'
   , rule_name     => 'Within Maintenance Hours'
   );
END;
/

以上语句,DBMS_MACUTL.G_RULESET_AUDIT_FAIL表示只有在评估失败时审计。

Creating DBV Secure Application Roles

利用之前创建的rule set来实现SAR(激活角色)。

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.create_role(
       role_name     => 'SH_DELETE_ROLE'
     , enabled       => 'Y'
     , rule_set_name => 'Inside Maintenance Window'
     );
END;
/

查看:

CONNECT sys@sales AS SYSDBA
column role format a15
column schema format a15
column package format a20
-- we can see that a role database object has been created
SELECT *
FROM dba_application_roles
WHERE role = 'SH_DELETE_ROLE';

ROLE            SCHEMA          PACKAGE
--------------- --------------- --------------------
SH_DELETE_ROLE  DVSYS           DBMS_MACSEC_ROLES

赋予此role删除和读取某表权限:

CONNECT sh@sales
GRANT SELECT ON sh.sales TO sh_delete_role;

将此role加入到realm:

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.add_object_to_realm (
      realm_name    => 'Sales History'
     ,object_owner  => 'SH'
     ,object_name   => 'SH_DELETE_ROLE'
     ,object_type   => 'ROLE'
     );
END;
/

创建测试用户lisa,也可直接用hr用户:

SQL> connect c##accts_admin_ace/password@sales
Connected.
SQL> grant create session to lisa identified by welcome1;

Grant succeeded.

这里无需将SH_DELETE_ROLE赋予用户lisa,也就是说,书中的以下语句是多余的,而且执行也不会成功

SQL> GRANT sh_delete_role TO lisa;
GRANT sh_delete_role TO lisa
      *
ERROR at line 1:
ORA-01924: role 'SH_DELETE_ROLE' not granted or does not exist

此时,由于不在维护期,因此也无法启用角色:

SQL> connect hr/oracle@sales
Connected.
SQL> SELECT * FROM session_roles;

ROLE
----------------------------------------
RESOURCE
SODA_APP

SQL> select * from sh.sales;
select * from sh.sales
                 *
ERROR at line 1:
ORA-00942: table or view does not exist


SELECT get_factor('CURRENT_DAY') DAY_OF_WEEK
, DVF.F$CURRENT_HOUR HOUR_OF_DAY
  3  FROM dual;

DAY_OF_WEEK          HOUR_OF_DAY
-------------------- --------------------
WED                  18

SQL> EXEC dvsys.dbms_macsec_roles.set_role('SH_DELETE_ROLE');
BEGIN dvsys.dbms_macsec_roles.set_role('SH_DELETE_ROLE'); END;

*
ERROR at line 1:
ORA-47305: Rule Set violation on SET ROLE (SH_DELETE_ROLE)
ORA-06512: at "DVSYS.DBMS_MACUTL", line 49
ORA-06512: at "DVSYS.DBMS_MACUTL", line 398
ORA-06512: at "DVSYS.DBMS_MACSEC", line 286
ORA-06512: at "DVSYS.ROLE_IS_ENABLED", line 4
ORA-06512: at "DVSYS.DBMS_MACSEC_ROLES", line 53
ORA-06512: at line 1

为了得到一个成功的例子,我们修改rule:

BEGIN
DBMS_MACADM.UPDATE_RULE(
		rule_name => 'Is Maintenance Day of Week'
       , rule_expr => 'GET_FACTOR(''Current_Day'') = ''WED'''
);
END;
/

BEGIN
DBMS_MACADM.UPDATE_RULE(
		rule_name => 'Within Maintenance Hours'
       , rule_expr => 'TO_NUMBER(GET_FACTOR(''Current_HOUR'')) BETWEEN 1 AND 23'
);
END;
/

然后用lisa登录测试:

SQL> connect hr/oracle@sales;
Connected.
SQL> SELECT get_factor('CURRENT_DAY') from dual;

GET_FACTOR('CURRENT_DAY')
--------------------------------------------------------------------------------
WED

SELECT get_factor('CURRENT_DAY') DAY_OF_WEEK
  2  , DVF.F$CURRENT_HOUR HOUR_OF_DAY from dual;

DAY_OF_WEEK          HOUR_OF_DAY
-------------------- --------------------
WED                  18

SQL> SELECT * FROM session_roles;

ROLE
----------------------------------------
RESOURCE
SODA_APP

SQL> EXEC dvsys.dbms_macsec_roles.set_role('SH_DELETE_ROLE');

PL/SQL procedure successfully completed.

SQL> SELECT * FROM session_roles;

ROLE
----------------------------------------
SH_DELETE_ROLE

SQL> select count(*) from sh.sales;

  COUNT(*)
----------
    918843

Creating Command Rules

command rule类似于trigger, 可应用于SQL语句和PL/SQL。

connect c##sec_admin_owen/password@sales

BEGIN
    dbms_macadm.create_command_rule (
       command       =>  'DROP TABLE'
     , rule_set_name => 'Inside Maintenance Window'
     , object_owner  => 'SH'
     , object_name   => '%'
     , enabled       => 'Y'
   );
END;
/

然后以对象属主登录:

SQL> connect sh@sales
Enter password:
Connected.
column DAY_OF_WEEK format a20
column HOUR_OF_DAY format a20
SQL>
SELECT get_factor('CURRENT_DAY') DAY_OF_WEEK
, DVF.F$CURRENT_HOUR HOUR_OF_DAY
  3  FROM dual;

DAY_OF_WEEK          HOUR_OF_DAY
-------------------- --------------------
WED                  18

SQL> DROP TABLE sh.sales_history;
DROP TABLE sh.sales_history
*
ERROR at line 1:
ORA-47400: Command Rule violation for DROP TABLE on SH.SALES_HISTORY

如果rule set评估为true,则可以删除成功:

SQL> DROP TABLE sh.sales;

Table dropped.

SQL> SHOW RECYCLEBIN;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
SALES            BIN$rcZhiHsZYTbgUwEAAH/Alg==$0 TABLE        2020-08-26:18:35:40
SQL> FLASHBACK TABLE SH.SALES TO BEFORE DROP;

Flashback complete.

SQL> select count(*) from sh.sales;

  COUNT(*)
----------
    918843

Disable DBV

做某些配置时需要禁用DBV。此处参考https://docs.oracle.com/en/database/oracle/oracle-database/19/dvadm/disabling-and-enabling-oracle-database-vault.html
先禁止PDB的, 以DV_OWNER用户登录:

CONNECT c##dbv_owner_root_backup@sales

EXEC DBMS_MACADM.DISABLE_DV;

然后重启PDB即可。

CDB如下操作:

CONNECT c##dbv_owner_root_backup@sales
EXEC DBMS_MACADM.DISABLE_DV;

然后重启数据库即可。

SQL> SELECT * FROM V$OPTION WHERE PARAMETER = 'Oracle Database Vault';

PARAMETER
----------------------------------------------------------------
VALUE                                                                CON_ID
---------------------------------------------------------------- ----------
Oracle Database Vault
FALSE                                                                     0


SQL> drop user c##sec_admin_owen;

User dropped.

SQL> drop user c##accts_admin_ace;

User dropped.

SQL> drop user c##dbv_owner_root_backup;

User dropped.

SQL> drop user c##dbv_acctmgr_root_backup;

User dropped.

参考

  • [https://docs.oracle.com/en/database/oracle/oracle-database/19/dvadm/index.html](Oracle® Database Vault Administrator’s Guide)
  • DBV Tutorial

你可能感兴趣的:(Oracle,12c,Oracle数据库安全)