随着计算机的普及以及网络的发展,数据库已经不再仅仅是那些程序员所专有的话题。而Oracle数据库更是凭借其性能卓越,操作方便灵活的特点,在数据库的市场中已经占据了一席之地。但是同样随着网络技术的不断进步,数据信息的不断增加,数据安全已经不再是以前的“老生长谈”,也更不是以前书本上那些“可望不可及”的条条框框。 或许很久以前,大家都觉得Oracle数据库的安全并不存在隐患,因为Oracle公司在去年11月份开始促销其数据库软件时提出的口号是“只有Oracle9i能够做到绝对安全”。但是不管它这么说是为了促销,还是为了扩大知名度,总之伴去年12 月份,英国的安全专家 David Litchfield 发现的9iAS 中存在的程序错误导致的缓冲溢出漏洞以及后来,PenTest Limited 和 eEye Digital Security 各自提出了一个小的漏洞,所有使用Oracle公司产品的人都不由地紧张了原本松弛的大脑--这个对于用户来说,毕竟关系到了自己的“身家性命”。 下面笔者将带着大家走进Oracle数据安全的世界。由于笔者水平有限,所以不足之处在所难免,望大家不吝赐教。 (一)Oracle数据库的一些基本常识 这里仅仅是为了以后的安全奠定一些基础,因为我们后面要用到它们。 1.Oracle所包含的组件: 在 Oracle,数据库是指整个 Oracle RDBMS 环境,它包括以下组件: ·Oracle 数据库进程和缓冲(实例)。 ·SYSTEM 表空间包含一个集中系统类目,它可以由一个或多个数据文件构成。 ·其它由数据库管理员 (DBA)(可选)定义的表空间,每个都由一个或多个数据文件构成。 ·两个以上的联机恢复日志。 ·归档恢复日志(可选)。 ·其它文件(控制文件、Init.ora、Config.ora 等)。 每个 Oracle 数据库都在一个中央系统类目和数据字典上运行,它位于SYSTEM 表空间。 2.关于“日志” Oracle数据库使用几种结构来保护数据:数据库后备、日志、回滚段和控制文件。下面我们将大体上了解一下作为主要结构之一的“日志”: 每一个Oracle数据库实例都提供日志,记录数据库中所作的全部修改。每一个运行的Oracle数据库实例相应地有一个在线日志,它与Oracle后台进程LGWR一起工作,立即记录该实例所作的全部修改。归档(离线)日志是可选择的,一个Oracle数据库实例一旦在线日志填满后,可形成在线日志归档文件。归档的在线日志文件被唯一标识并合并成归档日志。 ·关于在线日志:一个Oracle数据库的每一实例有一个相关联的在线日志。一个在线日志由多个在线日志文件组成。在线日志文件(online redo log file)填入日志项(redo entry),日志项记录的数据用于重构对数据库所作的全部修改。 ·关于归档日志:Oracle要将填满的在线日志文件组归档时,则要建立归档日志(archived redo log)。其对数据库备份和恢复有下列用处: <1>数据库后备以及在线和归档日志文件,在操作系统和磁盘故障中可保证全部提交的事物可被恢复。 <2>在数据库打开和正常系统使用下,如果归档日志是永久保存,在线后备可以进行和使用。 数据库可运行在两种不同方式下:NOARCHIVELOG方式或ARCHIVELOG 方式。数据库在NOARCHIVELOG方式下使用时,不能进行在线日志的归档。如果数据库在ARCHIVELOG方式下运行,可实施在线日志的归档。 3.物理和逻辑存储结构: Oracle RDBMS是由表空间组成的,而表空间又是由数据文件组成的。表空间数据文件被格式化为内部的块单位。块的大小,是由DBA在Oracle第一次创建的时候设置的,可以在512到8192个字节的范围内变动。当一个对象在Oracle表空间中创建的时候,用户用叫做长度的单位(初始长度((initial extent)、下一个长度(next extent)、最小长度(min extents)、以及最大长度(max extents))来标明该对象的空间大小。一个Oracle长度的大小可以变化,但是要包含一个由至少五个连续的块构成的链。 4.Oracle与Microsoft SQL Server比较下的联网协议: (二)Oracle数据安全的维护 记得某位哲学家说过:“事物的变化离不开内因和外因。”那么对于Oracle数据安全这个话题而言,也势必分为“内”和“外”两个部分。那么好,我们就先从“内”开始说起: §1.从Oracle系统本身说起 我们先抛开令人闻风色变的“hacker”和其他一些外部的原因,先想一下我们的数据库。什么硬盘 【一】解决系统本身问题的方法--数据库的备份及恢复 ·数据库的备份: 关于Oracle数据库的备份,标准地有三中办法:导出/导入(Export/Import)、冷备份、热备份。导出备份是一种逻辑备份,冷备份和热备份是物理备份。 <1>导出/导入(Export/Import) 利用Export可将数据从数据库中提取出来,利用Import则可将提取出来的数据送回Oracle数据库中去。 a.简单导出数据(Export)和导入数据(Import) Oracle支持三种类型的输出: (1)表方式(T方式),将指定表的数据导出。 (2)用户方式(U方式),将指定用户的所有对象及数据导出。 (3)全库方式(Full方式),将数据库中的所有对象导出。 数据导出(Import)的过程是数据导入(Export)的逆过程,它们的数据流向不同。 b.增量导出/导入 增量导出是一种常用的数据备份方法,它只能对整个数据库来实施,并且必须作为SYSTEM来导出。在进行此种导出时,系统不要求回答任何问题。导出文件名缺省为export.dmp,如果不希望自己的输出文件定名为export.dmp,必须在命令行中指出要用的文件名。 增量导出包括三个类型: (1)“完全”增量导出(Complete) 即备份整个数据库,比如: $exp system/manager inctype=complete file=990702.dmp (2)“增量型”增量导出 备份上一次备份后改变的数据。比如: $exp system/manager inctype=incremental file=990702.dmp (3)“累计型”增量导出(Cumulative) 累计型导出方式只是导出自上次“完全” 导出之后数据库中变化了的信息。比如: $exp system/manager inctype=cumulative file=990702.dmp 数据库管理员可以排定一个备份日程表,用数据导出的三个不同方式合理高效地完成。比如数据库的备份任务可作如下安排: ·星期一:完全导出(A) ·星期二:增量导出(B) ·星期三:增量导出(C) ·星期四:增量导出(D) ·星期五:累计导出(E) ·星期六:增量导出(F) ·星期日:增量导出(G) 如果在星期日,数据库遭到意外破坏,数据库管理员可按以下步骤来 第一步:用命令CREATE DATABASE重新生成数据库结构; 第二步:创建一个足够大的附加回段。 第三步:完全增量导入A: $imp system./manager inctype= RECTORE FULL=Y FILE=A 第四步:累计增量导入E: $imp system/manager inctype= RECTORE FULL=Y FILE =E 第五步:最近增量导入F: $imp system/manager inctype=RESTORE FULL=Y FILE=F <2>冷备份 冷备份发生在数据库已经正常关闭的情况下,当正常关闭时会提供给我们一个完整的数据库。冷备份是将关键性文件拷贝到另外位置的一种说法。对于备份Oracle信息而言,冷备份是最快和最安全的方法。冷备份的优点是: ·是非常快速的备份方法(只需拷贝文件) ·容易归档(简单拷贝即可) ·容易恢复到某个时间点上(只需将文件再拷贝回去) ·能与归档方法相结合,作数据库“最新状态”的恢复。 ·低度维护,高度安全。 但冷备份也有如下不足: ·单独使用时,只能提供到“某一时间点上”的恢复。 ·在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。 ·若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。 ·不能按表或按用户恢复。 如果可能的话(主要看效率),应将信息备份到磁盘上,然后启动数据库(使用户可以工作)并将所备份的信息拷贝到磁带上(拷贝的同时,数据库也可以工作)。冷备份中必须拷贝的文件包括: ·所有数据文件 ·所有控制文件 ·所有联机REDO LOG文件 ·Init.ora文件(可选) 值得注意的是冷备份必须在数据库关闭的情况下进行,当数据库处于打开状态时,执行数据库文件系统备份是无效的 下面是做冷备份的完整例子: (1) 关闭数据库$sqldba lmode=y SQLDBA >connect internal; SQLDBA >shutdown normal; (2) 用拷贝命令备份全部的时间文件、重做日志文件、控制文件、初始化参数文件 SQLDBA >! cp < file > < backup directory > (3) 重启Oracle数据库 $sqldba lmode=y SQLDBA >connect internal; SQLDBA >startup; <3>热备份 热备份是在数据库运行的情况下,采用archivelog mode方式备份数据的方法。所以,如果你有昨天夜里的一个冷备份而且又有今天的热备份文件,在发生问题时,就可以利用这些资料恢复更多的信息。热备份要求数据库在Archivelog方式下操作,并需要大量的档案空间。一旦数据库运行在archivelog状态下,就可以做备份了。热备份的命令文件由三部分组成: 1.数据文件一个表空间一个表空间地备份。 (1)设置表空间为备份状态 (2)备份表空间的数据文件 (3)恢复表空间为正常状态 2.备份归档log文件。 (1)临时停止归档进程 (2)log下那些在archive redo log目标目录中的文件 (3)重新启动archive进程 (4)备份归档的redo log 文件 3.用alter database backup controlfile命令来备份拷贝文件 热备份的优点是: ·可在表空间或数据文件级备份,备份时间短。 ·备份时数据库仍可使用。 ·可达到秒级恢复(恢复到某一时间点上)。 ·可对几乎所有数据库实体作恢复。 ·恢复是快速的,在大多数情况下在数据库仍工作时恢复。 热备份的不足是: ·不能出错,否则后果严重。 ·若热备份不成功,所得结果不可用于时间点的恢复。 ·因难于维护,所以要特别仔细小心,不允许“以失败而告终”。 【二】来自内部的另外一个隐患--用户管理以及密码问题 在这里,其实作为一个差不多点的数据库管理员都很清楚,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_HOME/DATABASE目录下。 ·密码文件的创建: 在使用Oracle Instance Manager创建一数据库实例的时侯,在ORACLE_HOME/DATABASE目录下还自动创建了一个与之对应的密码文件,文件名为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_HOME/DATABASE/PWDSID.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<‘1‘ then bcs:=‘7‘ ;end if; 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”在盯着你的数据库--因为这里面有他们想要的东西。 所以,请大家关注好下一个话题: §2.不被“hacker”入侵的几个建议 我们的目标是:没有蛀牙!(开个玩笑~!呵呵)其实应该是:它应尽可能地堵住潜在的各种漏洞,防止非法用户利用它们侵入数据库系统。对于数据库数据的安全问题,数据库管理员可以参考有关系统双机热备份功能以及数据库的备份和恢复的资料。 以下就数据库系统不被非法用户侵入这个问题作进一步的阐述。 ·组和安全性:在操作系统下建立用户组也是保证数据库安全性的一种有效方法。Oracle程序为了安全性目的一般分为两类:一类所有的用户都可执行,另一类只DBA可执行。在Unix环境下组设置的配置文件是/etc/group,关于这个文件如何配置,请参阅Unix的有关手册,以下是保证安全性的几种方法: (1)在安装Oracle Server前,创建数据库管理员组(DBA)而且分配root和Oracle软件拥有者的用户ID给这个组。DBA能执行的程序只有710权限。在安装过程中SQL*DBA系统权限命令被自动分配给DBA组。 (2)允许一部分Unix用户有限制地访问Oracle服务器系统,增加一个由授权用户组的Oracle组,确保给Oracle服务器实用例程Oracle组ID,公用的可执行程序,比如SQL*Plus,SQL*forms等,应该可被这组执行,然后该这个实用例程的权限为710,它将允许同组的用户执行,而其他用户不能。 (3)改那些不会影响数据库安全性的程序的权限为711。(注:在我们的系统中为了安装和调试的方便,Oracle数据库中的两个具有DBA权限的用户Sys和System的缺省密码是manager。为了您数据库系统的安全,我们强烈建议您该掉这两个用户的密码,具体操作如下: 在SQL*DBA下键入: alter user sys indentified by password; alter user system indentified by password; 其中password为您为用户设置的密码。 ·Oracle服务器实用例程的安全性: 以下是保护Oracle服务器不被非法用户使用的几条建议: (1) 确保$ORACLE_HOME/bin目录下的所有程序的拥有权归Oracle软件拥有者所有; (2) 给所有用户实用便程(sqiplus,sqiforms,exp,imp等)711权限,使服务器上所有的用户都可访问Oracle服务器; (3) 给所有的DBA实用例程(比如SQL*DBA)700权限。Oracle服务器和Unix组当访问本地的服务时,您可以通过在操作系统下把Oracle服务器的角色映射到Unix的组的方式来使用Unix管理服务器的安全性,这种方法适应于本地访问。 在Unix中指定Oracle服务器角色的格式如下: ora_sid_role[_dla] 其中 sid 是您Oracle数据库的oracle_sid; role 是Oracle服务器中角色的名字; d (可选)表示这个角色是缺省值;a (可选)表示这个角色带有WITH ADMIN选项,您只可以把这个角色授予其他角色,不能是其他用户。 以下是在/etc/group文件中设置的例子: ora_test_osoper_d:NONE:1:jim,narry,scott ora_test_osdba_a:NONE:3:pat ora_test_role1:NONE:4:bob,jane,tom,mary,jim bin: NONE:5:root,oracle,dba root:NONE:7:root 词组“ora_test_osoper_d”表示组的名字;词组“NONE”表示这个组的密码;数字1表示这个组的ID;接下来的是这个组的成员。前两行是Oracle服务器角色的例子,使用test作为sid,osoper和osdba作为Oracle服务器角色的名字。osoper是分配给用户的缺省角色,osdba带有WITH ADMIN选项。为了使这些数据库角色起作用,您必须shutdown您的数据库系统,设置Oracle数据库参数文件initORACLE_SID.ora中os_roles参数为True,然后重新启动您的数据库。如果您想让这些角色有connect internal权限,运行orapwd为这些角色设置密码。当您尝试connect internal时,您键入的密码表示了角色所对应的权限。 ·SQL*DBA命令的安全性: 如果您没有SQL*PLUS应用程序,您也可以使用SQL*DBA作SQL查权限相关的命令只能分配给Oracle软件拥有者和DBA组的用户,因为这些命令被授予了特殊的系统权限。 (1) startup (2) shutdown (3) connect internal ·数据库文件的安全性: Oracle软件的拥有者应该这些数据库文件($ORACLE_HOME/dbs/*.dbf)设置这些文件的使用权限为0600:文件的拥有者可读可写,同组的和其他组的用户没有写的权限。 Oracle软件的拥有者应该拥有包含数据库文件的目录,为了增加安全性,建议收回同组和其他组用户对这些文件的可读权限。 ·网络安全性: 当处理网络安全性时,以下是额外要考虑的几个问题。 (1) 在网络上使用密码在网上的远端用户可以通过加密或不加密方式键入密码,当您用不加密方式键入密码时,您的密码很有可能被非法用户截获,导致破坏了系统的安全性。 (2) 网络上的DBA权限控制您可以通过下列两种方式对网络上的DBA权限进行控制: A 设置成拒绝远程DBA访问; B 通过orapwd给DBA设置特殊的密码。 ·建立安全性策略: 系统安全性策略 (1)管理数据库用户:数据库用户是访问Oracle数据库信息的途径,因此,应该很好地维护管理数据库用户的安全性。按照数据库系统的大小和管理数据库用户所需的工作量,数据库安全性管理者可能只是拥有create,alter,或drop数据库用户的一个特殊用户,或者是拥有这些权限的一组用户,应注意的是,只有那些值得信任的个人才应该有管理数据库用户的权限。 (2) 用户身份确认:数据库用户可以通过操作系统,网络服务,或数据库进行身份确认,通过主机操作系统进行用户身份认证的优点有: A 用户能更快,更方便地联入数据库; B 通过操作系统对用户身份确认进行集中控制:如果操作系统与数据库用户信息一致,Oracle无须存储和管理用户名以及密码; C 用户进入数据库和操作系统审计信息一致。 (3) 操作系统安全性 A 数据库管理员必须有create和delete文件的操作系统权限; B 一般数据库用户不应该有create或delete与数据库相关文件的操作系统权限; C 如果操作系统能为数据库用户分配角色,那么安全性管理者必须有修改操作系统帐户安全性区域的操作系统权限。 ·数据的安全性策略: 数据的生考虑应基于数据的重要性。如果数据不是很重要,那么数据的安全性策略可以稍稍放松一些。然而,如果数据很重要,那么应该有一谨慎的安全性策略,用它来维护对数据对象访问的有效控制。 ·用户安全性策略: (1) 一般用户的安全性: A 密码的安全性:如果用户是通过数据库进行用户身份的确认,那么建议使用密码加密的方式与数据库进行连接。这种方式的设置方法如下: 在客户端的oracle.ini文件中设置ora_encrypt_login数为true; 在服务器端的initORACLE_SID.ora文件中设置dbling_encypt_login参数为true。 B 权限管理:对于那些用户很多,应用程序和数据对象很丰富的数据库,应充分利用“角色”这个机制所带的方便性对权限进行有效管理。对于复杂的系统环境,“角色”能大大地简化权限的理。 (2) 终端用户的安全性: 您必须针对终端用户制定安全性策略。例如,对于一个有很多用户的大规模数据库,安全性管理者可以决定用户组分类为这些用户组创建用户角色,把所需的权限和应用程序角色授予每一个用户角色,以及为用户分配相应的用户角色。当处理特殊的应用要求时,安全性管理者也必须明确地把一些特定的权限要求授予给用户。您可以使用“角色”对终端用户进行权限管理。 ·数据库管理者安全性策略: (1) 保护作为sys和system用户的连接: 当数据库创建好以后,立即更改有管理权限的sys和system用户的密码,防止非法用户访问数据库。当作为sys和system用户连入数据库后,用户有强大的权限用各种方式对数据库进行改动。 (2) 保护管理者与数据库的连接: 应该只有数据库管理者能用管理权限连入数据库,当以sysdba或startup,shutdown,和recover或数据库对象(例如create,drop,和delete等)进行没有任何限制的操作。 (3) 使用角色对管理者权限进行管理 ·应用程序开发者的安全性策略: (1) 应用程序开发者和他们的权限数据库应用程序开发者是唯一一类需要特殊权限组完成自己工作的数据库用户。开发者需要诸如create table,create,procedure等系统权限,然而,为了限制开发者对数据库的操作,只应该把一些特定的系统权限授予开发者。 (2) 应用程序开发者的环境: A 程序开发者不应与终端用户竞争数据库资源; B 用程序开发者不能损害数据库其他应用产品。 (3) free和controlled应用程序开发应用程序开发者有一下两种权限: A free development 应用程序开发者允许创建新的模式对象,包括table,index,procedure,package等,它允许应用程序开发者开发独立于其他对象的应用程序。 B controlled development 应用程序开发者不允许创建新的模式对象。所有需要table,indes procedure等都由数据库管理者创建,它保证了数据库管理者能完全控制数据空间的使用以及访问数据库信息的途径。但有时应用程序开发者也需这两种权限的混和。 (4) 应用程序开发者的角色和权限数据库安全性管理者能创建角色来管理典型的应用程序开发者的权限要求。 A create系统权限常常授予给应用程序开发者,以至于他们能创建他的数据对象。 B 数据对象角色几乎不会授予给应用程序开发者使用的角色。 (5) 加强应用程序开发者的空间限制作为数据库安全性管理者,您应该特别地为每个应用程序开发者设置以下的一些限制: A 开发者可以创建table或index的表空间; B 在每一个表空间中,开发者所拥有的空间份额。应用程序管理者的安全在有许多数据库应用程序的数据库系统中,您可能需要一应用程序管理者,应用程序管理者应负责起以下的任务: a)为每一个应用程序创建角色以及管理每一个应用程序的角色; b)创建和管理数据库应用程序使用的数据对象; c)需要的话,维护和更新应用程序代码和Oracle的存储过程和程序包。 我相信有了以上的这些建议,作为一个Oracle的管理者绝对可以做好他本职的工作了。可是,我们再怎么努力,都始终得面对这样一个现实,那就是Oracle毕竟是其他人开发的,而我们却在使用。所以,Oracle到底有多少漏洞--我想这个不是你和我所能解决的。不过既然作为一篇讨论Oracle数据安全的文章,我认为有必要把漏洞这一块也写进去,毕竟这也是“安全”必不可少的一部分。呵呵! 所以…… 【Oracle漏洞举例】: ·Oracle9iAS Web Cache远程拒绝服务攻击漏洞(2002-10-28) ·Oracle 8.1.6的oidldapd中的漏洞 ·Oracle 9iAS OracleJSP 泄漏JSP文件信息漏洞 ·Linux ORACLE 8.1.5漏洞 想必我没有理由再往下举了,因为读者肯定已经从其他有效的途径得到了关于Oracle漏洞的最新情报。我这里就不再赘述了。 总而言之一句话--“Oracle数据安全是一个博大而又精深的话题;如果你没有耐心,就永远不会得到它的精髓之所在。” 损坏,什么软件受损,什么操作事物……一系列由于我们的“疏忽”而造成的系统问题就完全可以让我们辛苦建立的数据库中的数据一去不复返。那么,我们就先从自己身上找找原因吧。恢复数据库: