[Oracle] 数据库安全之 - Oracle标签安全(OLS)

在上一篇文章中讨论了如何利用VPD对Oracle表中的行进行访问控制(见《[Oracle] 数据库安全之 - 虚拟私有数据库 (VPD)》),下面介绍一种比VPD复杂一点的访问控制技术——OLS (Oracle Label Security)。

启用OLS

如果你的数据库版本是10g,则需要额外安装OLS组件,但如果是11g,只要启用OLS即可,因为11g里OLS是默认安装的,下面是11g下启动OLS的语句:

C:\Users\xianzhu>chopt enable lbac

Writing to C:/app/xianzhu/product/11.2.0/dbhome_1/install/enable_lbac.log...
movefile C:\app\xianzhu\product\11.2.0\dbhome_1/bin/oralbac11.dll.dbl C:\app\xianzhu\product\11.2.0\dbhome_1/bin/oralbac11.dll

OLS启动成功,并重启数据库之后,再用sqlplus登陆数据库时,会发现多了"Oracle Label Security"的提示信息:

C:\Users\xianzhu>sqlplus test/test

SQL*Plus: Release 11.2.0.1.0 Production on 星期日 6月 9 09:40:17 2013

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining
and Real Application Testing options

启动OLS还是不够的,还需要用dbca配置OLS,其主要步骤如下:

[Oracle] 数据库安全之 - Oracle标签安全(OLS)_第1张图片

[Oracle] 数据库安全之 - Oracle标签安全(OLS)_第2张图片


OLS机制

[Oracle] 数据库安全之 - Oracle标签安全(OLS)_第3张图片

OLS和其它访问控制技术的关系如上图所示,从上图可以看出,OLS是在VPD之后起作用,它们都是针对行进行访问控制。当用户发起一个SQL访问数据时,其大致过程如下:

1)Check DAC (Data Access Control):查看用户对该表是否有访问(select)权限
2)VPD SQL Modification:如果在该表上有定义VPD,则启用VPD,加上相应的谓词条件
3)OLS:如果在该表上有定义OLS,则启动OLS,只返回用户可以看到的数据

OLS的机制如下图所示:

[Oracle] 数据库安全之 - Oracle标签安全(OLS)_第4张图片
其原理大致如下:
1)在表上定义伪列(Data Label),在该伪上定义每行数据的级别(如上例中Highly Sensitive, Sensitive, Confidential)
2)对用户也定义相应的级别(User Label),表上该用户能访问的最高级别
3)当用户访问表中数据时,Oracle会比较用户的Label和表中数据的Label,只有当用户的Label >= 数据的Label时,数据才会返回给用户

OLS实战

1)如果你照以上步骤,正确启用OLS之后,Oracle会创建一个用户lbacsys,但是该用户是被锁的,首次使用需要解锁并修改密码:

SQL> alter user lbacsys account unlock;

用户已更改。

SQL> alter user lbacsys identified by lbacsys;

用户已更改。

2)接着用lbacsys用户连接,并新建一个policy如下:

SQL> conn lbacsys/lbacsys
已连接。
SQL> exec sa_sysdba.create_policy(policy_name => 'ACCESS_LOCATIONS', column_name => 'OLS_COLUMNE');

PL/SQL 过程已成功完成。

SQL> select policy_name, status from dba_sa_policies;

POLICY_NAME                    STATUS
------------------------------ --------
ACCESS_LOCATIONS               ENABLED

3)创建3个level,从小到大分别是(‘PUBLIC CITY', 'CONFIDENTIAL CITY', 'SENSITIVE CITY'),注意:Oracle是用level_num来区分各个level的等级。

SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>1000,short_name=>'PUB',long_name=>'PUBLIC CITY');

PL/SQL 过程已成功完成。

SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>2000,short_name=>'CONF',long_name=>'CONFIDENTIAL CITY');

PL/SQL 过程已成功完成。

SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>3000,short_name=>'SENS',long_name=>'SENSITIVE CITY');

PL/SQL 过程已成功完成。

SQL> select * from dba_sa_levels order by level_num;

POLICY_NAME           LEVEL_NUM SHORT_NAME LONG_NAME
-------------------- ---------- ---------- --------------------
ACCESS_LOCATIONS           1000 PUB        PUBLIC CITY
ACCESS_LOCATIONS           2000 CONF       CONFIDENTIAL CITY
ACCESS_LOCATIONS           3000 SENS       SENSITIVE CITY

4)创建标签(label)

SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'1000',label_value=>'PUB',data_label=>TRUE);

PL/SQL 过程已成功完成。

SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'2000',label_value=>'CONF',data_label=>TRUE);

PL/SQL 过程已成功完成。

SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'3000',label_value=>'SENS',data_label=>TRUE);

PL/SQL 过程已成功完成。

SQL> exec sa_policy_admin.apply_table_policy(policy_name=>'ACCESS_LOCATIONS',schema_name=>'HR',table_name=>'LOCATIONS',table_options=>'LABEL_DEFAULT,READ_CONTROL');

PL/SQL 过程已成功完成。

5)创建三个测试用户(DBA账户):

SQL> create user tom identified by tom;

用户已创建。

SQL> create user peter identified by peter;

用户已创建。

SQL> create user rose identified by rose;

用户已创建。

SQL> grant connect to tom, peter, rose;

授权成功。

SQL> grant select on hr.locations to tom, peter, rose;

授权成功。

6)为以上三个用户创建user label,他们的label对应关系分别是:Tom -> SENS, Peter -> CONF, Rose -> PUB

SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'TOM',max_read_label=>'SENS');

PL/SQL 过程已成功完成。

SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'PETER',max_read_label=>'CONF');

PL/SQL 过程已成功完成。

SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'ROSE',max_read_label=>'PUB');

PL/SQL 过程已成功完成。

7)给表中数据的某一行标记label

SQL> execute sa_user_admin.set_user_privs(policy_name=>'ACCESS_LOCATIONS',user_name=>'HR',privileges=>'FULL');

PL/SQL 过程已成功完成。

SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','SENS') where upper(city) in ('BEIJING','TOKYO','SINGAPORE');

已更新3行。

SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','CONF') where upper(city) in ('MUNICH','OXFORD','ROME');

已更新2行。

SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','PUB') where ols_columne is null;

已更新18行。

8)至此,OLS已经部署完成,现在Tom可以看到所有的数据,Peter看不到'BEIJING','TOKYO','SINGAPORE'的数据,Rose看不到’BEIJING','TOKYO','SINGAPORE, 'MUNICH', 'OXFORD', 'ROME'数据。

你可能感兴趣的:(Oracle,深入Oracle)