【安全】Oracle 安全管理与审计(二)

《Oracle 安全管理与审计(二)》
新年新群招募: 中国Oracle精英联盟 170513055群介绍:本群是大家的一个技术分享社区,在这里可以领略大师级的技术讲座,还有机会参加Oracle举办的技术沙龙,与兴趣相投的小伙伴一起笑谈风云起,感悟职场情!
数据库版本

SYS@LEO1>select * from v$version;

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 – Production

操作系统信息

[oracle@leonarding1 admin]$ uname -a

Linux leonarding1.oracle.com 2.6.32-200.13.1.el5uek #1 SMP Wed Jul 27 21:02:33 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux

再谈Oracle安全管理

1.上一篇我们聊到《洪兴社的Oracle情节之安全管理篇(一)》 http://space.itpub.net/26686207/viewspace-763470

主要介绍了“安全认证” “TDE透明数据加密” “细粒度权限控制”这三个方面的Oracle安全技术。从原理到实践我们由浅入深分析了技术细节和应用场景,使大家从整体上了解Oracle技术的发展状态,下面展示一下Oracle安全产品的发展路线

下面是Oracle常见安全解决方案

本文重点讲述内容列表

1.VPN 虚拟私有数据库访问控制

2.OLS 标签安全访问控制

3.Database vault 数据库保险箱

4.FGA细粒度审计

5.SYS管理员级审计

什么是重点:Oracle产品的原理并不复杂,关键是知道在什么场合下适用什么样的产品,产品特性,带来的效果。

 

演示一个VPD进行数据访问控制的示例

1.什么是VPDVirtual Private Database 虚拟私有数据库,听起来像是一个独立自主的数据库,其实在逻辑上是独立的,物理上就是一个数据库。原理就是通过指定过滤策略,对用户的SQL添加谓词条件,来达到过滤数据的目的。

 

2.VPD优点:

精细化访问

对业务透明,不同的客户发出相同SQL语句,查询到的结果集不一样,可以让不同客户只看其相关的数据

对用户透明,用户感知不到

不对数据本身做任何操作,只在SQL层面进行过滤处理

VPD是数据库默认自带的,无需独立安装

 

3.实验

我们建一张业务表car,有汽车名,汽车数量,汽车价格三个字段,插入9条记录,分成高中低三个档次

LEO1@LEO1>create table car (name varchar2(20),num number,cost number);

Table created.

LEO1@LEO1>insert into car values('toyota',10,30);         高级车

1 row created.

LEO1@LEO1>insert into car values('volvo',50,30);

1 row created.

LEO1@LEO1>insert into car values('honda',60,30);

1 row created.

 

LEO1@LEO1>insert into car values('biaozhi',70,20);        中级车

1 row created.

LEO1@LEO1>insert into car values('xuetielong',80,20);

1 row created.

LEO1@LEO1>insert into car values('polo',90,20);

1 row created.

 

LEO1@LEO1>insert into car values('xiali',20,10);          低级车

1 row created.

LEO1@LEO1>insert into car values('jili',30,10);

1 row created.

LEO1@LEO1>insert into car values('byd',40,10);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from car;

NAME                        NUM       COST

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

toyota                       10         30

volvo                        50         30

honda                       60         30

biaozhi                      70         20

xuetielong                   80         20

polo                         90         20

xiali                         20         10

jili                          30         10

byd                         40         10

9 rows selected.

 

我们的思路:car表上添加过滤策略“filter_name”和“filter_num”,当select语句中有name字段时触发“filter_name”策略,当select语句中有num字段时触发“filter_num”策略,过滤策略由函数“fun_name”和“fun_num”实现。

 

创建函数“fun_name”

LEO1@LEO1>create or replace function fun_name (fun_scheme  varchar2,fun_object  varchar2)

return varchar2 as fun_cost varchar2(20);

begin

fun_cost:='cost=30';

return(fun_cost);

end fun_name;

/

  2    3    4    5    6    7 

Function created.

 

创建函数“fun_num”

LEO1@LEO1>create or replace function fun_num (fun_scheme varchar2,fun_object varchar2)

return varchar2 as fun_cost varchar2(20);

begin

fun_cost:='cost=10';

return(fun_cost);

end fun_num;

/

  2    3    4    5    6    7 

Function created.

 

添加过滤策略“filter_name”

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_name',

policy_function => 'fun_name',

sec_relevant_cols => 'name');

end;

/

  2    3    4    5    6    7    8    9 

PL/SQL procedure successfully completed.

 

添加过滤策略“filter_num”

 

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_num',

policy_function => 'fun_num',

sec_relevant_cols => 'num');

end;

/

 

  2    3    4    5    6    7    8    9 

PL/SQL procedure successfully completed.

 

当我们要查询汽车名的时候,会触发filter_name过滤策略,从而调用fun_name函数限制where cost=30的记录显示

LEO1@LEO1>select name,cost from car;

NAME                       COST

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

toyota                       30

volvo                        30

honda                       30

 

当我们要查询汽车数量的时候,会触发filter_num过滤策略,从而调用fun_num函数限制where cost=10的记录显示

LEO1@LEO1>select num,cost from car;

       NUM       COST

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

        20         10

        30         10

        40         10

 

当我们不想使用过滤策略的时候,如何删除?

 

使用drop_policy存储过程来删除,filter_name和filter_num过滤策略

LEO1@LEO1>execute dbms_rls.drop_policy('leo1','car','filter_name');

PL/SQL procedure successfully completed.

 

LEO1@LEO1>execute dbms_rls.drop_policy('leo1','car','filter_num');

PL/SQL procedure successfully completed.

 

LEO1@LEO1>select * from car;

NAME                        NUM       COST

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

toyota                       10         30

volvo                        50         30

honda                        60         30

biaozhi                      70         20

xuetielong                   80         20

polo                         90         20

xiali                        20         10

jili                         30         10

byd                          40         10

9 rows selected.

 

利用VPD隐藏敏感列信息

我们设计一个新的“filter_num”策略,只显示cost=10的记录,隐藏num列的汽车数量

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_num',

policy_function => 'fun_num',

sec_relevant_cols => 'num',

sec_relevant_cols_opt => dbms_rls.all_rows);      只显示相关的行信息

end;

/

  2    3    4    5    6    7    8    9   10 

PL/SQL procedure successfully completed.

 

LEO1@LEO1>select * from car;

NAME                        NUM       COST

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

toyota                                   30

volvo                                    30

honda                                   30

biaozhi                                  20

xuetielong                               20

polo                                    20

xiali                         20         10

jili                          30          10

byd                         40          10

9 rows selected.

小结:VPD是一种行级安全控制,操作简单无需添加任何组件即可实施。

 

演示一个OLS进行数据访问控制的示例

1.什么是OLSOracle Label Security 甲骨文标签安全访问控制,通过创建标签来过滤结果集,这种方式会修改表结构,会增加一列叫“标签列”又叫“伪列”,通过给不同的记录指定不同的标签,从而达到显示不同的结果集。OLSVPD功能更强大一些,并且不是数据库默认自带的,需要独立安装。

 

2.Oracle Label Security的安装

Oracle 10g 安装OLS

运行Oracle程序安装文件

./runInstaller 安装组件->选择“Oracle Label Security 10.2.0.1.0

 

Oracle 11g 安装OLS

11g不需安装OLS组件,已经安装好了,只需要启动就好。

Red Hat Linux

1[oracle@leonarding1 oracle]$ chopt enable lbac                启动OLS,写入OLS日志

 

Writing to /u02/app/oracle/product/11.2.0/db_1/install/enable_lbac.log...

%s_unixOSDMakePath% -f /u02/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk lbac_on

%s_unixOSDMakePath% -f /u02/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk ioracle

 

2)启动dbca安装Oracle Label Security数据库对象和专属用户

[oracle@leonarding1 oracle]$ dbca

配置数据库选项,点击“下一步”

选择哪个数据库->LEO1” 点击“下一步”

Oracle Label Security 组件上挑勾,点击“下一步”

这里就出现了不可思议的场景,Oracle Label Security是灰框框,不可打勾,如果这里是白框框那么恭喜你可以成功继续下一步了。当然没有安装上的筒子们也不要气馁,条条大路通罗马,请看下面的脚本方法。

 

Oracle Label Security 组件的脚本安装法

1)我们使用Oracle自带的OLS安装脚本来部署OLS组件$ORACLE_HOME/rdbms/admin/catols.sql

[oracle@leonarding1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Fri Jun 14 18:57:08 2013

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

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

SYS@LEO1>@?/rdbms/admin/catols.sql

<<<<<<<<<<<<<<省略脚本执行信息>>>>>>>>>>>>>>>

请注意在创建完数据库对象后会自动关闭数据库,你需要重新启动

Database closed.

Database dismounted.

ORACLE instance shut down.

 

2)检查OLS专属用户LBACSYS的状态,正常安装脚本后为OPEN,如果是LOCKED,请执行下面解锁步骤

SYS@LEO1>select username,account_status from dba_users;

。。。。。。省略无用内容。。。。。。

USERNAME                       ACCOUNT_STATUS

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

LBACSYS                         OPEN

SYS                             OPEN

SYSTEM                         OPEN

OUTLN                          EXPIRED & LOCKED

MGMT_VIEW                     EXPIRED & LOCKED

33 rows selected.

解锁并设置密码,如果要是OPEN状态,可跳过这一步

alter user lbacsys account unlock;

alter user lbacsys identified by lbacsys;

小结:LBACSYSOLS管理员用户,安装OLS之后就会自动创建,如果有锁请解锁即可使用。

 

3)检查LBACSYS用户中涉及到的数据库对象信息

LBACSYS用户中不存在无效的数据库对象。

SYS@LEO1>select object_type,object_name from dba_objects where owner='LBACSYS' and status='INVALID';

no rows selected

SYS@LEO1>set pagesize 999           设置999行才有一个分界符

SYS@LEO1>select object_type,count(*) from dba_objects where owner='LBACSYS' group by object_type;

OBJECT_TYPE           COUNT(*)

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

SEQUENCE                     2

PROCEDURE                    5

LIBRARY                       10

PACKAGE                      24

LOB                           1

PACKAGE BODY                 23

TYPE BODY                     5

TRIGGER                       3

FUNCTION                     35

TABLE                         21

INDEX                        28

VIEW                         57

TYPE                         10

13 rows selected.

这就是Oracle Label Security所使用的数据库对象,以上我们完成了Oracle Label Security组件的安装。

4)如何卸载Oracle Label Security组件

有安装脚本自然就会有卸载脚本,执行catnools.sql脚本就可自动卸载OLS

SYS@LEO1>@?/rdbms/admin/catnools.sql

PL/SQL procedure successfully completed.           删除存储过程

 

PL/SQL procedure successfully completed.

 

Trigger dropped.                                删除触发器

 

Trigger dropped.

 

Trigger dropped.

 

PL/SQL procedure successfully completed.          

 

PL/SQL procedure successfully completed.

 

User dropped.                                  最后删除用户

 

2 rows deleted.

 

Commit complete.

先删除Oracle Label Security对应的数据库对象再删除LBACSYS用户。

5)如何使用好Oracle Label Security

创建标签策略

SYS@LEO1>alter user lbacsys identified by lbacsys;      设置密码

User altered.

 

SYS@LEO1>conn lbacsys/lbacsys                     切换lbacsys用户

Connected.

 

LBACSYS@LEO1>execute sa_sysdba.create_policy(policy_name => 'ACCESS_LEO1',column_name => 'OLS_COLUMN');

BEGIN sa_sysdba.create_policy(policy_name => 'ACCESS_LEO1',column_name => 'OLS_COLUMN'); END;

 

*

ERROR at line 1:

ORA-00439: feature not enabled: Oracle Label Security

ORA-06512: at "LBACSYS.LBAC_SYSDBA", line 113

ORA-06512: at "LBACSYS.SA_SYSDBA", line 44

ORA-06512: at line 1

####################################################################################################

 

安装database vault

1)启动chopt enable dv 服务

2)依赖Oracle Label Security

3)重启数据库startup force

4dbca创建数据库对象

 

启动chopt enable dv 服务

[oracle@leonarding1 ~]$ chopt enable dv

 

Writing to /u02/app/oracle/product/11.2.0/db_1/install/enable_dv.log...

%s_unixOSDMakePath% -f /u02/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk dv_on

%s_unixOSDMakePath% -f /u02/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk ioracle

 

演示一个通过触发器进行审计的示例。

Car表是一个非常重要的表,记录了4S店汽车的销量情况,我们要对操作这个表动作进行审计

LEO1@LEO1>select * from car;

 

NAME                        NUM       COST

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

toyota                       10         30

volvo                        50         30

honda                        60         30

biaozhi                      70         20

xuetielong                   80         20

polo                         90         20

xiali                        20         10

jili                         30         10

byd                          40         10

 

9 rows selected.

创建审计表car_audit

LEO1@LEO1>create table car_audit (

name varchar2(20),

num number,

cost number,

uuser varchar2(20),

ddate date);  2    3    4    5    6 

 

Table created.

 

创建审计触发器

LEO1@LEO1>create trigger trg_car_audit

after insert or delete or update on car

for each row

declare

a_name  varchar2(20);

a_num   number;

a_cost  number;

begin

a_name :=:old.name;

a_num  :=:old.num;

a_cost :=:old.cost;

insert into car_audit values(a_name,a_num,a_cost,user,sysdate);

end;

/

  2    3    4    5    6    7    8    9   10   11   12   13   14 

Trigger created.

删除记录

LEO1@LEO1>delete from car where num=100;

1 row deleted.

LEO1@LEO1>commit;

Commit complete.

插入记录

LEO1@LEO1>insert into car values('kia',100,50);

1 row created.

LEO1@LEO1>commit;

Commit complete.

更新记录

LEO1@LEO1>update car set num=200 where num=100;

1 row updated.

LEO1@LEO1>commit;

Commit complete.

凡是对car表进行DML操作都会触发审计触发器,并在car_audit表中留下审计记录

LEO1@LEO1>select * from car_audit;

NAME        NUM      COST      UUSER                DDATE

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

kia            100       50       LEO1                 15-JUN-13

                                  LEO1                 15-JUN-13

kia            100       50       LEO1                 15-JUN-13

 

分别演示对sys用户和普通用户进行审计的示例。

我们在操作数据库的时候,知道SYS用户的权限是最大的干什么事很方便,同时带来的问题就是非常危险,没有人可以束缚住。因此我们有时需要对SYS用户进行审计

SYS@LEO1>show parameter audit

NAME                                 TYPE        VALUE

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

audit_file_dest                      string      /u02/app/oracle/admin/LEO1/adump

audit_sys_operations                 boolean     FALSE        默认SYS用户审计是关闭的,这个参数是开启审计SYS用户所有SQL语句

audit_syslog_level                   string                    默认是关闭的,这个参数指出SYS用户审计日志的存放位置

audit_trail                          string      DB

SYS@LEO1>alter system set audit_sys_operations=true scope=spfile;         打开SYS用户审计

 

System altered.

SYS@LEO1>alter system set audit_syslog_level='user.notice' scope=spfile;     用户日志

 

System altered.

SYS@LEO1>startup force                                          重启数据库使静态参数生效

ORACLE instance started.

 

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             285214152 bytes

Database Buffers          176160768 bytes

Redo Buffers                8241152 bytes

Database mounted.

Database opened.

SYS@LEO1>show parameter audit

 

NAME                                 TYPE        VALUE

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

audit_file_dest                      string      /u02/app/oracle/admin/LEO1/adump

audit_sys_operations                 boolean     TRUE             审计启动

audit_syslog_level                   string      USER.NOTICE   

audit_trail                          string      DB

 

设置sys用户审计日志输出位置,Linux syslog.conf文件配置了各种类型日志的输出位置和消息源

我们只需要将Oracle日志输出配置信息添加到该文件中就可以了

[root@leonarding1 log]# vi /etc/syslog.conf

添加如下信息

# About Oracle SysLog

user.notice                                            /var/log/oracle_dbms

 

添加完之后,我们还要重新加载一下配置信息,syslog.conf文件生效

[root@leonarding1 log]# ps -ef | grep syslogd

root      2385     1  0 Jun14 ?        00:00:01 syslogd -m 0

root     29740 29502  0 17:25 pts/1    00:00:00 grep syslogd

[root@leonarding1 log]# kill -HUP 2385                        重新加载

Ok,操作系统的配置内容完成了。

下面我们来演示一下SYS用户的审计

SYS@LEO1>create table test as select * from dba_objects;      我们创建一个表

 

Table created.

 

SYS@LEO1>drop table test purge;                          再删除一个表

 

Table dropped.

 

好了,SYS用户操作做完了,我们来看看oracle_dbms审计日志中有没有抓取到SQL语句

[root@leonarding1 log]# cat oracle_dbms

Jun 15 18:08:40 leonarding1 Oracle Audit[29903]: LENGTH : '199' ACTION :[46] 'create table test as select * from dba_objects' DATABASE USER:[1] '/' PRIVILEGE :[6] 'SYSDBA' CLIENT USER:[6] 'oracle' CLIENT TERMINAL:[5] 'pts/3' STATUS:[1] '0' DBID:[10] '1692458681'

Jun 15 18:08:49 leonarding1 Oracle Audit[29903]: LENGTH : '174' ACTION :[21] 'drop table test purge' DATABASE USER:[1] '/' PRIVILEGE :[6] 'SYSDBA' CLIENT USER:[6] 'oracle' CLIENT TERMINAL:[5] 'pts/3' STATUS:[1] '0' DBID:[10] '1692458681'

Good 创建表test和删除表test的命令都抓取到了,例如 startup  shutdown  connect等操作都是可以抓取到的。

小结:通过上面的测试实例,我们了解到了对数据库管理员的审计也逐渐成为信息安全中的重要一项,这样可以对管理员人员进行监督,权限限制,提高数据库安全级别,完善安全管理制度。这里提及一个问题,为什么SYS用户的操作记录需要记录在操作系统文件中呢,这里就有一个渊源了,由于SYS用户本身权力就大,大到可以把自己的操作记录都可以删除,因此为了节制SYS用户,就把记录操作的日志放在了操作系统下面,还不是普通用户可以访问的,必须是操作系统管理员才能查看,这下同学们应该知道原委了吧。

 

普通用户审计的示例

我们既可以对SYS用户进行审计,那么在平时的时候更多的是对普通用户的审计,对普通用户的审计就没有这么严格了,它的审计记录是可以放在数据库基表sys.aud$中的,我们可以在数据库层面上进行查看。

标准审计内容

1)审计会话

2)审计对象

3)审计操作

4)审计授权

实验

SYS@LEO1>show user

USER is "SYS"

SYS@LEO1>alter system set audit_trail=db,extended scope=spfile;          启动审计追逐数据库功能

 

System altered.

 

SYS@LEO1>startup force;                                           重启数据库使静态参数生效

ORACLE instance started.

 

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             285214152 bytes

Database Buffers          176160768 bytes

Redo Buffers                8241152 bytes

Database mounted.

Database opened.

 

我们计划对leo1用户的car表进行审计

SYS@LEO1>audit select,insert,update,delete on leo1.car;

 

Audit succeeded.

指定审计对象和审计动作,对select,insert,update,delete这四个操作Oracle都会进行审计。

 

 

插入记录

LEO1@LEO1> insert into leo1.car values('mini',150,150);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1> select * from car;

。。。。。。省略。。。。。。

LEO1@LEO1>select userid,obj$name,sqltext from sys.aud$;

USERID           OBJ$NAME          SQLTEXT

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

LEO1             CAR                select * from car

LEO1             CAR                insert into leo1.car values('mini',150,150)

 

VPD  OLS  db vault  audit  sys用户

 

刘盛Leonarding
2013.6.16
北京&summer
分享技术~成就梦想
Blog:www.leonarding.com

 

##########################################################################################
如果喜欢我的文章就请扫下面二维码吧!关注微信号:leonarding_public
在这里你能得到技术、实事、热点消息等新兴事物的思考和观点,别的地方可能没有的东西。我将为大家提供最新技术与资讯动态,传递正能量。


请使用浏览器的分享功能分享到微信等