在这里,其实作为一个差不多点的数据库管理员都很清楚,Oracle数据库本身就使用了很多种手段来加强数据库的安全性,经常见到的就有密码,角色,权限等等。那么我们就从最简单的DBSNMP
说起:
Oralce数据库如果采用典型安装后,自动创建了一个叫做DBSNMP的用户,该用户负责运行Oracle系统的智能代理 (Intelligent Agent),该用户的缺省密码也是“DBSNMP”。如果忘记修改该用户的口令,任何人都可以通过该用户存取数据库系统。现在我们来看一下该用户具有哪 些权限和角色,然后来分析一下该用户对数据库系统可能造成的损失。
启动SQL/PLUS程序,使用该用户登录进入:
SQL> select * from session_privs;
CREATE SESSION
ALTER SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE CLUSTER
CREATE SYNONYM
CREATE PUBLIC SYNONYM
CREATE VIEW
CREATE SEQUENCE
CREATE DATABASE LINK
CREATE PROCEDURE
CREATE TRIGGER
ANALYZE ANY
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE
可以看到该用户不是SYS或SYSTEM管理用户,然而,它却具有两个系统级权限:UNLIMITED TABLESPACE和CREATE PUBLIC SYNONYM。
看到这两个权限你应该马上想到,这些都是安全隐患,尤其是UNLIMITED TABLESPACE,它是破坏数据库系统的攻击点之一。如果这时候你还依然认为,即使有人利用这个没有修改的口令登录进数据库也造成不了什么损失的话, 我就不得不提醒你:该用户具有UNLIMITED TABLESPACE的系统权限,它可以写一个小的脚本,然后恶意将系统用垃圾数据填满,这样数据库系统也就无法运行,并将直接导致最终的瘫痪。目前很多 数据库系统都要求7X24的工作,如果出现了系统用垃圾数据填满的情况,那么,等数据库系统恢复时,恐怕不可挽回的损失已经造成了。
可是除了 DBSNMP 还有很多其他的用户,怎么办呢?让我们先看一下目前普遍存在于Oracle数据库中的用户管理问题:
(1)权限过大:对ORACLE数据库编程和浏览的一般用户常常具有DBA (数据库管理员权限),
能对数据库系统做任何修改或删除。
(2)安全性差:很多ORACLE用户缺省存储位置都在系统表空间,这样不仅影响系统的正常工
作,而且不同用户的数据信息互相影响、透明,保密性差。随着数据的不断加入,
有可能使整个数据库系统崩溃。
(3)密码有规律:在ORACLE调试初期形成的用户名和密码一致的不良习惯保留到现在;系统用户SYS和SYSTEM的密码也众所皆知。
知道了这些普遍的“毛病”,我们怎么做呢?下面是我的一些建议:
(1)ORACLE DBA (数据库管理员)的规范
·SUN Solaris操作系统下ORACLE用户密码应严格保密,绝不该把密码设成
ORACLE;并指定专门的数据库管理员定期修改。
·ORACLE初始化建立的SYS和SYSTEM系统管理员用户密码应由原来MANAGER改成别的不易被记忆的字符串。
·ORACLE WEB SERVER的管理端口具备DBA浏览数据库的能力,因此其管理者
ADMIN的密码也应保密,不该把密码设成MANAGER;并指定专门的数据库管理员定
期修改。
·ORACLE DBA最好在SUN SPARC服务器控制台上用窗口式界面实现管理。前提
是ORACLE用户启动服务器,然后在窗口式命令行下输入SVRMGRM,即启动了ORACLE SERVER MANAGER菜单式管理;用SYSDBA身份登录后,就可做数据库系统维护工作了
(2)SQL*PLUS编程用户的规范
·存储结构的规范
考虑到用SQL*PLUS编程可实现各行各业、各公司、各部门多种多样的应用需求,我们的SQL*PLUS编程用户也应该朝这个方向规范:不同 种类的应用必须有不同的用户;不同种类的应用必须有不同的存储位置,包括物理文件、缺省表空间、临时表空间的创建和规划:当准备编写某一较大规模(从 ORACLE数据量和面向用户量考虑)应用程序时,首先应该创建一个逻辑的存储位置-表空间,同时定义物理文件的存放路径和所占硬盘的大小。
①、物理文件缺省的存放路径在/oracle_home/dbs下,在命令行下用UNIX指令df -k 可查看硬盘资源分区的使用情况。如果oracle_home使用率达90‰以上,而且有一个或多个较为空闲的硬盘资源分区可以利用,我们最好把物理文件缺 省的存放路径改到较为空闲的硬盘资源分区路径下。在此路径下我们可以这样规划资源物理文件的存储:
xxx表空间
xxx行业/ xxx公司/ xxx 部门/ xxx 服务.dbf
DEMO表空间
default_datafile_home1/col /elec/sys4/demo1.dbf
default_datafile_home1/col /elec/sys4/demo2.dbf
公司系统四部摹拟演示系统物理文件
HUMAN表空间
default_datafile_home1/col/elec/human/human.dbf
公司人事部人事管理系统物理文件
BOOK表空间
default_datafile_home1/col/elec/book/book.dbf
公司资料室图书管理系统物理文件
QUESTION表空间
default_datafile_home1/col/elec/client/question.dbf
公司客户服务部问题库系统物理文件
PC表空间
default_datafile_home1/col/chaoxun/client/pc.dbf
公司PC机售后服务系统物理文件
……表空间
default_datafile_home2/……………………………
等等
说明:其中default_datafile_home1指oracle_home/dbs;
default_datafile_home2指较为空闲的硬盘资源分区路径。
②、物理文件的大小根据应用系统的数据量、数据对象、程序包的多少来定。一般用于摹拟演示的小系统,表空间初始的物理文件为2M即能满足要求, 如果信息量满,还可以增加物理文件,扩充表空间(每次扩充大小也可暂定为2M);一般实际运行的应用系统可适当增加表空间初始的物理文件大小,但也不要一 次分配太大(因为不易回收空间,却易扩充空间),这也需要根据具体情况具体分析:信息量大、需长时间保存的应用在条件允许情况下,表空间可以大到几百M甚 至上G;信息量小、短期经常刷新的应用,表空间可以控制在2M以下。
③、表空间的名称应该采用同系统应用相似的英文字符或字符缩写,表空间所对应的一个或多个物理文件名也应有相关性。不同用户所处的缺省表空间不 同,存储的信息就不能互相访问。这比把所有用户信息都储存在系统表空间,安全性大大提高了。如果用ORACLE WEB SERVER管理端口创建的用户,其缺省和临时表空间一定是系统表空间,DBA切记要改变用户的缺省表空间。临时表空间存放临时数据段,处理一些排序、合 并等中间操作,根据实际应用的需求可以把它们放在专门创建的表空间里;如果系统表空间大,也可以把它们放在系统表空间。用户创建的数据索引最好和数据文件 分开存放在不同表空间,以减少数据争用和提高响应速度。
·密码和用户名的规范
有相当数量的ORACLE用户名和密码一致,这是个很不安全的因素。我们建议ORACLE用户名和密码一定不要一样,密码最好在五,六位字符以 上。不同用户间不应该使用相同的密码。用户名的定义可根据实际应用的英文名来设,而依据编程人员的姓名定义的用户名实际上不规范,可在日后的工作中结合上 述有关存储结构规范的说明逐步改进。
(3)特殊要求用户的规范
在ORACLE数据库使用过程中,还会遇到一些有特殊要求的用户:非编程人员需要对某个表有查询、增加、删除、修改的权利。DBA应创建一个这 样的用户,先确定用户名和密码,再规定相关应用所在缺省表空间(包含某个表)和临时表空间,最后TABLE属主给其授权:赋予CONNECT角色 SELECT、INSERT、DELETE、UPDATE ON THE TABLE的对象级权限,这可根据实际需求自由取舍。
举例:●给新用户授于对象级权限(命令行方式):
假设新用户NEW2需要有查询、删除、修改DCD用户的表EMP。
%svrmgrl
SVRMGR>connect internal; 以系统管理员登录
SVRMGR>create user new2 identified by new2345 default tablespace app;
SVRMGR>connect dcd/dcdpwd; 以dcd用户登录
SVRMGR>grant connect to new2;
SVRMGR>grant select on emp to new2;
SVRMGR>grant delete on emp to new2;
SVRMGR>grant update on emp to new2;
说了这么多关于用户的问题,那么接下来我们就详细得说一下关于密码文件的使用以及维护--在Oracle数据库系统中,用户如果要以特权用户身 份(INTERNAL/SYSDBA/SYSOPER)登录Oracle数据库可以有两种身份验证的方法:即使用与操作系统集成的身份验证或使用 Oracle数据库的密码文件进行身份验证。因此,管理好密码文件,对于控制授权用户从远端或本机登录Oracle数据库系统,执行数据库管理工作,具有 重要的意义。
Oracle数据库的密码文件存放有超级用户INTERNAL/SYS的口令及其他特权用户的用户名/口令,它一般存放在ORACLE_HOMEDATABASE目录下。
·密码文件的创建:
在使用Oracle Instance Manager创建一数据库实例的时侯,在ORACLE_HOMEDATABASE目录下还自动创建了一个与之对应的密码文件,文件名为 PWDSID.ORA,其中SID代表相应的Oracle数据库系统标识符。此密码文件是进行初始数据库管理工作的基础。在此之后,管理员也可以根据需 要,使用工具ORAPWD.EXE手工创建密码文件,命令格式如下:
C: >ORAPWD FILE=< FILENAME > PASSWORD =< PASSWORD > ENTRIES=< MAX_USERS >
各命令参数的含义为:
FILENAME:密码文件名;
PASSWORD:设置INTERNAL/SYS帐号的口令;
MAX_USERS:密码文件中可以存放的最大用户数,对应于允许以SYSDBA/SYSOPER权限登录数据库的最大用户数。由于在以后的维护中,若用户数超出了此限制,则需要重建密码文件,所以此参数可以根据需要设置得大一些。
有了密码文件之后,需要设置初始化参数REMOTE_LOGIN_PASSWORDFILE来控制密码文件的使用状态。
·设置初始化参数REMOTE_LOGIN_PASSWORDfile:
在Oracle数据库实例的初始化参数文件中,此参数控制着密码文件的使用及其状态。它可以有以下几个选项:
NONE:指示Oracle系统不使用密码文件,特权用户的登录通过操作系统进行身份验证;
EXCLUSIVE:指示只有一个数据库实例可以使用此密码文件。只有在此设置下的密码文件可以包含有除INTERNAL/SYS以外的用户信息,即允许将系统权限SYSOPER/SYSDBA授予除INTERNAL/SYS以外的其他用户。
SHARED:指示可有多个数据库实例可以使用此密码文件。在此设置下只有INTERNAL/SYS帐号能被密码文件识别,即使文件中存有其他用户的信息,也不允许他们以SYSOPER/SYSDBA的权限登录。此设置为缺省值。
在REMOTE_LOGIN_PASSWORDFILE参数设置为EXCLUSIVE、SHARED情况下,Oracle系统搜索密码文件的次 序为:在系统注册库中查找ORA_SID_PWFILE参数值(它为密码文件的全路径名);若未找到,则查找ORA_PWFILE参数值;若仍未找到,则 使用缺省值ORACLE_HOMEDATABASEPWDSID.ORA;其中的SID代表相应的Oracle数据库系统标识符。
·向密码文件中增加、删除用户:
当初始化参数REMOTE_LOGIN_PASSWORDFILE设置为EXCLUSIVE时,系统允许除INTERNAL/SYS以外的其他 用户以管理员身份从远端或本机登录到Oracle数据库系统,执行数据库管理工作;这些用户名必须存在于密码文件中,系统才能识别他们。由于不管是在创建 数据库实例时自动创建的密码文件,还是使用工具ORAPWD.EXE手工创建的密码文件,都只包含INTERNAL/SYS用户的信息;为此,在实际操作 中,可能需要向密码文件添加或删除其他用户帐号。
由于仅被授予SYSOPER/SYSDBA系统权限的用户才存在于密码文件中,所以当向某一用户授予或收回SYSOPER/SYSDBA系统权 限时,他们的帐号也将相应地被加入到密码文件或从密码文件中删除。由此,向密码文件中增加或删除某一用户,实际上也就是对某一用户授予或收回 SYSOPER/SYSDBA系统权限。
要进行此项授权操作,需使用SYSDBA权限(或INTERNAL帐号)连入数据库,且初始化参数REMOTE_LOGIN_PASSWORDFILE的设置必须为EXCLUSIVE。具体操作步骤如下:
创建相应的密码文件;
设置初始化参数REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE;
使用SYSDBA权限登录: CONNECT SYS/internal_user_passsword AS SYSDBA;
启动数据库实例并打开数据库;
创建相应用户帐号,对其授权(包括SYSOPER和SYSDBA): 授予权限:GRANT SYSDBA TO user_name;
收回权限:REVOKE SYSDBA FROM user_name;
现在这些用户可以以管理员身份登录数据库系统了;
·使用密码文件登录:
有了密码文件后,用户就可以使用密码文件以SYSOPER/SYSDBA权限登录Oracle数据库实例了,注意初始化参数 REMOTE_LOGIN_PASSWORDFILE应设置为EXCLUSIVE或SHARED。任何用户以SYSOPER/SYSDBA的权限登录后, 将位于SYS用户的Schema之下,以下为两个登录的例子:
1. 以管理员身份登录:
假设用户scott已被授予SYSDBA权限,则他可以使用以下命令登录:
CONNECT scott/tiger AS SYSDBA
2. 以INTERNAL身份登录:
CONNECT INTERNAL/INTERNAL_PASSWORD
·密码文件的维护:
1. 查看密码文件中的成员:
可以通过查询视图V$PWFILE_USERS来获取拥有SYSOPER/SYSDBA系统权限的用户的信息,表中SYSOPER/SYSDBA列的取值TRUE/FALSE表示此用户是否拥有相应的权限。这些用户也就是相应地存在于密码文件中的成员。
2. 扩展密码文件的用户数量:
当向密码文件添加的帐号数目超过创建密码文件时所定的限制(即ORAPWD.EXE工具的MAX_USERS参数)时,为扩展密码文件的用户数限制,需重建密码文件,具体步骤如下:
a) 查询视图V$PWFILE_USERS,记录下拥有SYSOPER/SYSDBA系统权限的用户信息;
关闭数据库;
c) 删除密码文件;
d) 用ORAPWD.EXE新建一密码文件;
e) 将步骤a中获取的用户添加到密码文件中。
3. 修改密码文件的状态:
密码文件的状态信息存放于此文件中,当它被创建时,它的缺省状态为SHARED。可以通过改变初始化参数 REMOTE_LOGIN_PASSWORDFILE的设置改变密码文件的状态。当启动数据库事例时,Oracle系统从初始化参数文件中读取 REMOTE_LOGIN_PASSWORDFILE参数的设置;当加载数据库时,系统将此参数与口令文件的状态进行比较,如果不同,则更新密码文件的状 态。若计划允许从多台客户机上启动数据库实例,由于各客户机上必须有初始化参数文件,所以应确保各客户机上的初始化参数文件的一致性,以避免意外地改变了 密码文件的状态,造成数据库登陆的失败。
4. 修改密码文件的存储位置:
密码文件的存放位置可以根据需要进行移动,但作此修改后,应相应修改系统注册库有关指向密码文件存放位置的参数或环境变量的设置。
5. 删除密码文件:
在删除密码文件前,应确保当前运行的各数据库实例的初始化参数REMOTE_LOGIN_PASSWORDFILE皆设置为NONE。在删除密码文件后,若想要以管理员身份连入数据库的话,则必须使用操作系统验证的方法进行登录。
但是管理员都觉得乏味,因为在管理员中流行一种很简单的加密办法--就是经常,很频繁地修改自己的密码。可是,每次修改都跟打一次仗似的--因为更新程序并不是每个人都愿意做的事情。
那么有没有什么简单点的办法呢?请往下看:
模型:Oracle7.3;开发工具:Develope2000。收费系统(在数据库中的名称是SFYY),其Client端分散在市区的数个营业点,通过城域网与主机(小型 机)相连。
过程:
·在收费小型机Oracle系统的system用户(DBA)下,创建新用户test;?
create user test?
identified by carton?
default tablespace dataspace1?
quota 100K?
·对test用户授以权限;?
grant create session to test;?
grant resource to test;?
·在test用户下建立一个存储函数mmtranslate,它其实是一个加密程序。下面是一个简 单的例子。?
function mmtranslate(m varchar2)?
return varchar2?
as?
i number(2);?
kk varchar2(10);?
begin?
kk:=′′;?
i:=1;?
loop?
if i<=length(m) then?
if instr(′1234567890′,substr(m,i,1),1,1)>0 then?
kk:=kk||chr(100+to_number(substr(m,i,1)));?
elseif instr(‘wxyz‘,substr(m,i,1),1,1)>0 then?
kk:=kk||chr(-8+ascii(substr(m,i,1)));?
else?
kk:=kk||chr(4+ascii(substr(m,i,1)));?
end if;?
else?
exit;?
end if;?
i:=i+1;?
end loop;?
return kk;?
exception?
when others then?
return ′-1′;?
end;?
·在test用户下建表mmtest并插入记录:?
create table mmtest?
(usnamevarchar2(6),------用户名称?
mimavarchar2(6)------加密前的密码);?
insert into mmtest values( ‘sfyy‘,‘eds2‘);?
commit;
·执行以下语句?
SQL>select mmtranslate(‘eds2‘) from dual;?
MMTRANSLATE(‘EDS2‘)?
----------------------------------------?
ihwf?
利用DBA权限更改sfyy的密码为上面语句的执行结果:?
alter user sffy?
identified by ihwf; ;?
·修改应用程序,对于开发环境是Develope2000的程序来说,主要是修改主程序的on-lo gon触发器:?
declare?
mm varchar2(6);?
begin?
logon(‘test‘,‘carton‘);?
select mima into mm from mmtest where usname=‘sfyy‘;?
mm:=mmtranslate(mm);?
logout;?
logon(‘sfyy‘,mm);?
end;?
然后再利用触发器WHEN-NEW-FROM-INSTANCE执行Callfrom或Newform等 命令,进入业务处理程序。这个主程序应当仅仅由管理员来掌握,编译之后将执行文件下发 到各收费点的Clien端。?
·在System用户下,利用Oracle提供的pupbld.sql,建立表Productuserprofile,执行下面这样的命令,限制在非开发状态Sql命令的使用,例如?
insert into productuserprofile?
(product,userid,attribute,charvalue) values?
(‘SQL*Plus‘,‘TEST‘,‘CONNECT‘,‘DISABLED‘);?
insert into productuserprofile?
(product,userid,attribute,charvalue) values?
(‘SQL*Plus‘,‘SFYY‘,‘DELETE‘,‘DISABLED‘);这样,在SQL状态下,根本无法连接到TEST用户,而在 sfyy用户下,delete命令将不能执行。当然,DBA可以改变这些设置。
当然了,这个仅仅是属于一种“应用技巧”,但是足可以把那些每天忙于更新系统的管理员舒服好几天了。但是另一方面,还要加强对源程序的管理,在Client端只存放执行程序。加强审计,发现异常现象,及时处理。这样才可以做到更高一层的“安全”。
在下面,我主要是向大家介绍一个REM对GHXXB制立数据库触发子,密码的加密程序。
REM 对GHXXB制立数据库触发子(当INSERT OR UPDATE GHXXB时触发)
drop trigger scjmmm;
create or replace trigger scjmmm
before insert or update of mm On ghxxb For each Row
Begin
:new.mm:=ENCRYPT(:new.mm,:NEW.GH,TO_CHAR(SYSDATE,‘SS‘));
End;
/
---------------------------密码的加密程序ENCRYPT----------------------
Create or Replace
Function ENCRYPT (Inpass In Varchar2,IN_GH In Varchar2,IN_SS In Varchar2)
Return Varchar2 Is
bcs varchar2(20);
bcs1 number;
cs number;
jg number;
m_gh VARCHAR2(4);
m_mm VARCHAR2(20);
Begin
m_gh:=IN_GH;
m_mm:=INPASS;
cs:=TO_NUMBER(IN_SS);
If cs<=1 then cs:=77 ;end if;
bcs:=substr(to_char(ascii(substr(m_gh,1,1))),1,2);
If bcs
m_gh:=substr(m_gh,2);
Loop EXIT WHEN nvl(length(m_gh),0)=0 ;
bcs:=bcs||substr(to_char(ascii(substr(m_gh,1,1))),-1,1);
m_gh:=substr(m_gh,2);
End loop;
Loop EXIT WHEN nvl(length(m_mm),0)=0 ;
bcs:=bcs||substr(to_char(ascii(substr(m_mm,1,1))),-1,1);
m_mm:=substr(m_mm,2);
End loop;
bcs1:=to_number(bcs);
jg:=cs*bcs1;
Loop EXIT WHEN length(to_char(jg))>13;
jg:=jg*cs ;
End loop;
RETURN(IN_SS||substr(to_char(jg),1,14));
End;
/
总结上面的东西,我们仅仅是从自身做起,知道了怎么维护Oracle数据库安全这个话题的“皮毛”。可是,对于这个似乎永远也说不完的话题,我 们光知道怎么从内部“防御”就够了吗?不要忘了,在外面,还有一群虎视耽耽的“hacker”在盯着你的数据库--因为这里面有他们想要的东西。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/77580/viewspace-212687/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/77580/viewspace-212687/