数据的安全
按层面划分:
网络层
- 防火墙
- vpn
系统层
- 操作系统漏洞
- 病毒、木马
应用层
- 数据加密
- 认证
- SQL注入
- 数据库层
Oracle的安全方案:
用户管理(相关产品:Advanced Security)
- 安全密码
- 用户管理
- 强认证
- 代理认证
- 基本的安全配置
访问控制(相关产品:VPD、Database Vault)
- 控制用户的权限
- 控制who、when、where访问what数据
- 数据权限
- 行级安全性
- 数据分类
- 多级安全管理
数据保护(相关产品:Advanced Security、TDE、Secure Backup)
- 数据加密
- 网络加密
- 数据隐藏
- 导出加密
- 备份加密
监控(相关产品:Database vault、Audit Vault)
- 数据库审计
- 细粒度审计
- 审计报告和预警
- 安全配置扫描
Oracle的认证
Oracle的认证方式:
- 数据库认证(普通用户)
密码保存在数据库中,需要数据库处于open状态。
- 密码文件认证(具有SYSDBA角色的用户)
密码保存在密码文件中
- 操作系统认证
操作系统级别的认证,只要用户登录进了操作系统,就可以不用密码直接登录。
数据库认证:
# 需要输入用户名/密码,oracle把密码和数据库中的进行比对
sqlplus test/test
密码文件认证:
# 在数据库实例没有启动的情况下,使用以下命令
# 数据库实例没有启动,而且登录的是sysdba身份的用户,oracle会和密码文件中的密码进行比对
sqlplus test/test as sysdba
操作系统认证:
# 当前操作系统登录的用户具有dba权限,直接登录
sqlplus / as sysdba
密码文件认证时,密码文件保存位置:$ORACLE_HOME/database/PWD实例名.ora
,例如:
D:\PC_Software\Program_Software\DataBase_Software\Database_Server\oracle\app\Administrator\product\11.2.0\dbhome_1\database\PWDorcl.ora
创建密码文件:
# orapwd是oracle安装的系统命令
# orapwd file=<密码文件名> entries=<该密码文件中最多可以放多少个用户密码>
# 命令参数的等号两边不可以有空格
orapwd file=OraPwdOrcl entries=30
操作系统认证的设置:
在sqlnet.ora文件中设置,$ORACLE_HOME/network/admin/sqlnet.ora
:
SQLNET.AUTHENTICATION_SERVICES=(NTS)
该配置有三个选项:
- ALL:对于Linux设置为all或者默认,可以进行操作系统认证。
- NTS:对于Windows,设置为NTS可以进行操作系统认证
- NULL:windows下不能进行操作系统认证
设置为all时,windwos 下使用sqlplus / as sysdba
登录会报错:
ORA-12641:验证服务无法初始化
设置为null时,windows下使用sqlplus / as sysdba
登录会报错:
ORA-01031: insufficient privileges
Oracle的权限管理
查看Oralce的权限(privilege):
select * from dba_sys_privs;
查看oracle的角色(role):
select * from dba_roles;
角色和权限对应关系:
select * from role_sys_privs;
给用户赋予单一的权限:
-- 将查看sys.tab$表的权限赋给test用户
grant select on sys.tab$ to test;
给用户赋予角色:
grant connect to test; -- 给用户resource角色
grant resource to test; -- 给用户resource角色
oraclce Advanced Security产品
功能:
- 数据加密(Data Encryption)
- 强验证机制(Strong Authentication)
Oracle透明加密技术(TDE)
TDE(Tranparent Data Encryption)
- 基于列的加密
- 基于表空间的加密(oracle 11g)
优势:
- 数据列进行加密,列依然可以建索引
- 对应用透明
- 管理简便,无需应用设置
限制:
- 只能使用 B-Tree 索引
- 加密的列无法对索引进行 range scan 操作
- 不能对外部对象加密
- 不能对可传输表空间加密
- 不能进行exp/imp操作
基于列的加密的机制
oracle有一个外部安全模块(External Security Module),可以产生一个Wallet钱包(Master Key),外部模块通过Wallet进行加密后传给Oracle内部。
Oracle内部 Data Dictionary 有列的密钥(Column Keys),对外部模块传入的内容再做一次加密。
配置步骤
使用TDE进行基于列的加密:
需要保证数据库版本高于10g R2
需要设置wallet钱包的位置
在$ORACLE_HOME/network/admin/sqlnet.ora
中添加配置:ENCRYPTION_WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = # 指定钱包路径 (DIRECTORY=D:\app\xxxx\wallet) ) )
TDE支持的加密算法:
- 3DES168
- AES128
- AES192(default)
- AES256
加密配置步骤:
- 在wallet里面创建key
-- 授权访问。 -- myPassword不是key的值,而是要访问这个key时需要输入的密码 alter system set encryption key authenticated by "myPassword";
oracle会自动在sqlnet.ora配置的钱包文件夹中创建wallet文件
创建表时,对指定列加密
create table tde_test( id number(10) primary key, info varchar2(50) encrypt using 'AES192' );
- 查看系统表中加密的列
select * from dba_encrypted_columns;
对加密表查询
如果要查询加密表,需要打开wallet:
-- 打开wallet
alter system set wallet open identified by 'myPassword';
此时使用sql查询时感觉不到加密的存在(对应用透明):
select * from tde_test;
对索引的影响
关闭wallet后无法查看表信息:
-- 关闭wallet
alter system set wallet close identified by 'myPassword';
此时查询tde_test
表时,会报错:
ORA-28365:Wallet未打开
只有将加密列的属性设置为 no salt
时,才可以创建索引,否则会报错:
ORA-28338:不能同时使用 salt 值索引和加密列
设置加密列为 no salt
:
alter table tde_test modify info encrypt no salt;
此时可以为加密列正常创建索引:
-- 为加密列创建索引
create index idx_td on tde_test(info);
可以使用加密列索引进行等值查询:
-- 使用索引列进行等值查询
select * from tde_test where info='test'
但是对加密列建索引后,该索引不能走 range scan:
-- tde_test2表对数值型的id设置为加密列,然后添加索引
-- 此时对id进行范围扫描时,可以正常查出数据,但是没有走索引范围扫描,而是走的全表扫描
select * from tde_test2 where id < 2;
使用in
进行查询时依然可以走索引:
-- oracle 会将in语句转换成or语句:select * from t where id=1 or id=2 or id=3
-- 此时会走索引
select * from t where id in (1, 2, 3);
加密表空间
创建加密表空间,该表空间上的表都会被加密,不再是对某张表的某个字段进行加密。
语句:
-- 创建加密表空间
create tablespace tde_tablespace
encryption using 'AES256'
default storage(encrypt);
查看表空间是否为加密表空间:
select tablespace_name, encrypted from dba_tablespaces;
和加密字段的区别:
表空间加密是发生在数据存储的时候,也就是存储在文件上的数据已经被加密。字段加密发生在SQL层,由SQL调用一个算法对数据进行加密处理。
表空间加密的数据,不会再受到字段加密的限制,例如:
- 字段类型
- 索引类型
- 需要
no salt
创建索引
-- 在加密表空间上可以正常的创建表
create table t tablespace tde_tablespace as select * from dba_objects;
-- 可以创建索引,不再受no salt限制
create index idx_t on t(object_id);
-- 可以正常走索引范围扫描
select * from t where object_id < 10;
加密表空间的限制:
- 外部大对象(bfiles)不可以
- 不可以使用exp/imp,需要使用 expdp/impdp
当wallet关闭时,加密表空间上的数据全部无法访问:
-- 关闭wallet
alter system set encryption wallet close identified by 'myPassword2';
此时查询表空间上的表时,会报错:
ORA-28365:Wallet未打开
此时在该表空间上创建表时,也会报一样的错。
总结
TDE的用途:
- 保护敏感的数据,禁止未授权的人访问
- 防止数据的丢失。别人即使导出拿到数据文件,也会因为没有wallet而无法查看真实数据
- 防止数据在传递过程中被截获
数据访问安全
Oracle数据访问安全的相关产品:
- VPD(Virtual Private Database)
- OLS(Oracle Label Security)
优势:
- 更精细的访问控制
- 对业务透明
VPD
VPD(Virtual Private Database):Oracle自带的细粒度权限产品,通过指定策略,对用户的SQL添加过滤的谓词,来达到过滤数据的目的。
例如:
A部门的用户发出一条SQL:select * from t
时,只能查看到deptNo='A'
的数据。B部门的用户发出同样的SQL,只能看到deptNo='B'
的数据。
操作:
创建函数:
-- 指定一个函数,返回要添加的where条件
create or replace function hide_sal_comm(v_schema varchar2, v_object varchar2)
return varchar2 as
con varchar2(200);
begin
con:='deptNo=30';
return(con);
end hid_sal_comm;
添加策略:
begin
dbms_rls.add_policy(
object_schema => 'scott', -- 用户
object_name => 'emp', -- 表名
policy_name => 'hide_sal_policy', -- 策略名
policy_function => 'hide_sal_comm', -- 生成where条件的函数
sec_relevant_cols => 'sal,comm' -- 只有用户查询字段带有sal或者comm字段时才启用规则
);
end;
此时发出查询emp:
-- 只能查看到 deptNo=30 的数据
select * from emp;
-- 没有查询sal或者comm字段,所以会显示所有数据
select deptNo from emp;
-- 只能看到 dept=30 的数据
select deptNo,sal from emp;
也可以实现隐藏敏感列的数据:
begin
dbms_rls.add_policy(
object_schema => 'scott',
object_name => 'emp',
policy_name => 'hide_sal_policy',
policy_function => 'hide_sal_comm',
sec_relevant_cols => 'sal,comm',
sec_relevant_cols_opt => dbms_rls.all_rows -- 显示所有行,但是敏感列的内容置空
);
end;
此时查询emp表:
-- 此时会返回表中所有的行。但是只有deptNo=30的行中字段sal、comm有值,其他行的sal、comm为空,其他字段可以正常显示。
select * from emp;
删除策略:
exec dbms_rls.drop_policy('scott', 'emp', 'hide_sal_policy');
OLS
OLS(Oracle Label Security):在Oracle 10g时默认没有安装OLS,需要在安装Oracle时勾选Oracle Label Security
。在Oracle 11g时,已经默认集成到了Oracle产品中,只需启用即可。
Oracle 11g 启用OLS:
chopt enable lbac
使用该命令后,oracle会将
$ORACLE_HOME/bin/
下的oralbac.dll.dbl
重命名成oralbac.dll
。所以直接将该文件重命名也可以启用该服务。
启用OLS后,需要重启Oracle服务。
启用OLS之后,使用sqlplus连接数据库时,输出的信息中,在oracle版本号下面,会出现Oracle Label Security
。
启用OLS之后,还需要对数据库进行一些配置才能使用:
- 使用命令进入Database Configuration Assistant:
dbca
选择
配置数据库选件
;数据库组件中勾选
Oracle Label Security
后面一直
下一步
即可
这个过程,oracle会在数据库中创建OLS需要用到的用户、用户视图等相关内容。
Oracle的SQL权限工作机制:
OLS会在对应的表上增加一个伪列(称为标签label),通过这个标签上的策略控制数据访问权限。
例如,创建如下的安全策略:
姓名 | 标签等级 | 权限 |
---|---|---|
Tom | SENSITIVE | ‘BEIJING’,’TOKYO’,’SIINGAPORE’ |
Peter | CONFIDENTIAL | ‘MUNICH’,’OXFORD’,’ROME’ |
Rose | PUBLIC | 其他 |
创建策略:
-- 配置了OLS后,数据库中就会自动加入lbacsys用户,需要先将该用户解锁、设置密码
-- 使用lbacsys用户连入数据库
conn lbacsys/lbacsys
-- 创建策略
exec sa_sysdba.create_policy(
policy_name => 'ACCESS_LOCATIONS', -- 策略名称
column_name => 'OLS_COLUMN' -- 字段名(要访问的表会增加一个伪列,这个是指定伪列的列名)
);
-- 查看所有策略
select policy_name, status from DBA_SA_POLICIES
创建等级:
-- 创建PUBLIC标签等级
exec sa_components.create_level(
policy_name => 'ACCESS_LOCATIONS', -- 策略名
level_num => 1000, -- 数字越大级别越高,高等级可以访问低等级的数据
short_name => 'PUB', -- 缩写名称
long_name => 'PUBLIC CITY' -- 完整名称
);
-- 创建CONFIDENTIAL标签等级
exec sa_components.create_level(
policy_name => 'ACCESS_LOCATIONS',
level_num => 2000,
short_name => 'CONF',
long_name => 'CONFIDENTIAL CITY'
);
-- 创建SENSITIVE标签等级
exec sa_components.create_level(
policy_name => 'ACCESS_LOCATIONS',
level_num => 2000,
short_name => 'SENS',
long_name => 'SENSITIVE CITY'
);
查看创建的等级:
select * from dba_sa_levels order by level_num;
创建标签:
-- 创建1000标签,级别对应到PUB
exec sa_label_admin.create_label(
policy_name => 'ACCESS_LOCATIONS', -- 策略名
LABEL_TAG => '1000', -- 标签名
LABEL_VALUE => 'PUB', -- 对应到level
DATA_LABEL => TRUE
);
-- 创建2000标签,级别对应到CONF
exec sa_label_admin.create_label(
policy_name => 'ACCESS_LOCATIONS',
LABEL_TAG => '2000',
LABEL_VALUE => 'CONF',
DATA_LABEL => TRUE
);
-- 创建3000标签,等级对应到SENS
exec sa_label_admin.create_label(
policy_name => 'ACCESS_LOCATIONS',
LABEL_TAG => '3000',
LABEL_VALUE => 'SENS',
DATA_LABEL => TRUE
);
-- 将策略应用到表上
exec sa_policy_admin.apply_table_policy(
policy_name => 'ACCESS_LOCATION', -- 策略名
schema_name => 'HR', -- 用户名
table_name => 'T_LOCATIONS', -- 表名
table_options => 'LABEL_DEFAULT' -- 表的选项
)
给用户设置策略和标签级别:
exec sa_user_admin.set_user_labels(
policy_name => 'ACCESS_LOCATIONS', -- 策略名称
user_name => 'TOM', -- 用户名
max_read_label => 'SENS' -- 用户可以读取的该策略下的标签level
);
exec sa_user_admin.set_user_labels(
policy_name => 'ACCESS_LOCATIONS',
user_name => 'PETER',
max_read_label => 'CONF'
);
exec sa_user_admin.set_user_labels(
policy_name => 'ACCESS_LOCATIONS',
user_name => 'ROSE',
max_read_label => 'PUB'
);
给表中的每行数据设置标签值:
exec sa_user_admin.set_user_labels(
policy_name => 'ACCESS_LOCATIONS',
user_name => 'HR',
privileges => 'FULL'
);
update t_locations set ols_column = char_to_label('ACCESS_LOCATIONS', 'SENS')
where city in ('BeiJing', 'Tokyo','Singapore');
update t_locations set ols_column = char_to_label('ACCESS_LOCATIONS', 'CONF')
where city in ('Munich', 'Oxford', 'Rome');
update t_locations set ols_column = char_to_label('ACCESS_LOCATIONS', 'PUB')
where city is null;
后续该表如果插入了新的数据,也需要接着为新插入的数据也设置标签值。
查看标签:
select * from hr.t_locations order by city;
可以看到,表中多了一个伪列OLS_COLUMN
,该字段的值是Label_Tag
。
使用不同用户查询该表时,只会显示该用户有权限的标签的数据行。
删除相关信息:
exec sa_label_admin.drop_label(
policy_name => 'ACCESS_LOCATIONS',
label_tag => 1000
);
exec sa_label_admin.drop_label(
policy_name => 'ACCESS_LOCATIONS',
label_tag => 2000
);
exec sa_label_admin.drop_label(
policy_name => 'ACCESS_LOCATIONS',
label_tag => 3000
);
exec sa_policy_admin.remove_table_policy(
policy_name => 'ACCESS_LOCATIONS',
schema_name => 'HR',
table_name => 'T_LOCATIONS'
);
exec sa_sysdba.drop_policy(
policy_name => 'ACCESS_LOCATIONS'
);
Database Vault
oracle 10g需要另外下载 database vault安装包。11g 已经整合到数据库安装包中,直接配置使用即可。
Database Vault:通过将权限限定在特定范围内(Realms域方式、命令集方式),来达到安全的目的。最重要的是解决了对sysdba角色的用户管理。
Realms域方式:将数据划分成不同的域,不同域的DBA用户不能访问没有权限的域数据。
Command Rule Flexibility(命令集)方式:给用户设置具体的命令权限。
11g配置启用Database Vault:
# 启用Database Vault
chopt enable dv
# 重启数据库服务
net stop oracleserviceorcl
net start oracleserviceorcl
windows下,使用chopt
启用database vault后,会将$ORACLE_HOME/bin/
下的oradv.dll.dbl
重命名为oradv.dll
文件。
重启数据库服务后,使用sqlplus
连接数据库时,可以看到服务中多了Oracle Database Vault
服务。
使用dbca
命令打开 Database Configuration Assistant,配置 Database Vault:
- 选择
配置数据库选件
- 勾选
Oracle Database Vault
- 创建一个Database Vault的用户,并设置密码
- 等待安装完成即可
oracle建议使用OEM网页对Database Vault进行配置。也可以使用oci中的包、存储过程进行配置。使用OEM配置比较简单。
Database Vault管理页面的地址、端口和OEM一样,假如OEM地址为:https://localhost:1158/em/,那么Database Vault管理页面为:https://localhost:1158/dva/
审计
审计层面:
- Trigger:based Auditing(触发器)
- Auditing the sys User:Sys用户审计
- Standard Auditing:标准审计
- Managing the Audit Trail:审计日志管理
触发器审计:
create trigger tra_a_idu_r_emp_sal
after insert or delete or update of sal on emp
for each row
begin
if(:NEW.sal > :OLD.sal * 1.10)
then insert into emp_sal_audit value(:OLD.empno, :OLD.sal, :NEW.sal, user, sysdate);
end if;
end;
sys用户的审计:
alter system set audit_sys_operations=true,scope=spfile;
sys用户审计日志会写到系统日志中,且该路径不是oracle自带路径,而是操作系统的日志路径。
标准审计:(普通数据库用户的审计)
alter system set audit_trail=DB, extended_scope=spfile
会保存在数据库的aud$
视图中,也可以配置成写到操作系统中。放在操作系统会存在$ORACLE_BASE/admin/sid/adump
路径下。
可以审计的内容:
- 审计会话
- 审计对象
- 审计操作
- 审计授权
对表审计:
-- 对test用户的t表审计
audit select,insert,update,delete on test.t;
查看审计日志:
select * from sys.aud$;
管理审计数据:
sys.aud$
- 操作系统文件:
$ORACLE_BASE/admin/sid/adump
- audit vault审计保险柜
- sys用户放在syslog中
Audit Vault
Aduit Vault: 集中管理审计数据
- 统一保管审计数据
- 告警机制
- 提供报告
- 审计策略统一管理
可以在OEM企业管理器中管理Audit Vault,例如:https://localhost:1158/av/
Audit Vault是Oracle的审计数据统一管理的产品,但是它也可以对 Sql Server、ASE、DB2等数据库,以及Text文本文件的审计信息进行抽取管理。
Audit Vault支持的数据库版本:
- Oracle 9iR2、10g、11g
- Sql Server 2000、2005、2008
- DB2 8.2、9.1、9.5,(Linux、Unix、Windows)
- Sybase ASE 12.5.4 - 15.0.x