操作项目
- 使用硬编码的口令标识脚本。
- 为实施挑选一种方法:
- 在 SQL 脚本内部使用 Connect 命令
- 在 shell 脚本内部使用 Connect 命令(无 SQL 脚本)
- 使用口令文件
- 使用 OS 验证的帐户
- 修改脚本以删除口令。
3.2 从 RMAN 中删除口令
背景 硬编码的口令并不局限于脚本。恢复管理器 (RMAN) 脚本容易受到相同不良习惯的影响。
下面是一个用于备份的脚本内部的典型 RMAN 命令: rman target=/ rcvcat=catowner/catpass@catalog_connect_string
在该命令中,connect 字符串 catalog_connect_string 中引用了目录数据库,该目录的用户 ID 和口令分别是 catowner 和 catpass。如前所述,如果某人执行 ps 命令,则会清楚地看到该用户 ID 和口令。
删除这些硬编码的口令有两种方法:
方法 1.在该方法中,请在 RMAN 脚本内部使用 connect 字符串,如下所示: connect target /
connect catalog catowner/catpass@catalog_connect_string
run {
allocate channel ...
... 等等...
这显然是首选方法 - 不仅是因为它从过程列表中隐藏了口令,还因为它使得检查目录 connect 字符串中的错误更加容易了。
方法 2.另一种方法是对目录连接使用 OS 验证。但是您需要进行一些额外的更改。首先,目录可能位于不同的数据库中,而不是位于正被备份的数据库中。要在这种情况下启用 OS 验证,您需要对目录数据库启用远程 OS 验证。
在目录数据库上,添加下列初始化参数,然后重新启动。 remote_os_authent=TRUE
现在,在 catalog 数据库上创建一个用户 ID OPS$ORACLE,如下所示。 create user ops$oracle identified externally;
现在,您的 RMAN 连接将如下所示: rman target=/ rcvcat=/@catalog_connect_string
这将不会显示 RMAN 用户的口令或口令。
由于您现在是以 OPS$ORACLE 而不是 catowner 的身份连接的,因此必须重建信息库。连接之后,使用 RMAN> register database;
命令重建目录。您现在准备在 RMAN 备份中使用此脚本。 可能的影响 此处有一些可能的影响。首先,目录数据库中的更改使具有登录身份“oracle”的任何人可以从外部服务器对该数据库进行访问。这是其自身的一个严重的安全漏洞;由于您无法控制客户端,因此某人可能会进入客户端服务器(可能通过一个本身不安全的操作系统),创建一个称作“oracle”的 ID,并登录到目录数据库。
有多种方法可以避免这样的进入。最简单的方法是启用节点过滤(如 3.8 所述),以防任何随机服务器连接到该节点。
此外,您还应意识到,源数据库服务器上的 Oracle 软件所有者可能具有不同的名称。如果您在数据库服务器 A 上使用“orasoft”,而在数据库服务器 B 上使用“oracle”,则您需要在目录数据库上创建的用户分别是 OPS$ORASOFT 和 OPS$ORACLE。因此,将存在两个信息库,而不是一个。这并不一定是坏事。但是,如果您想要对目录中的备份进行报告,则您必须知道数据库中的所有信息库。 操作计划
- 选择一种用于隐藏 RMAN 目录所有者口令的方法:
- 在脚本内部使用 Connect 命令
- 以 OS 验证的用户身份连接
- 如果选择 b.,则
- 对目录数据库启用远程 OS 验证(需要重新启动)。
- 在目录数据库中启用节点验证,以拒绝除已知的少数几个节点之外的所有节点。
- 创建名为 OPS$ORACLE 的用户。
- 修改 RMAN 目录连接字符串以使用 OPS$ORACLE。
- 重建目录。
3.3 将 DBA 脚本移动到计划程序
背景 那些需要登录数据库来执行统计数据收集、索引重建等操作的非常常见的 DBA 脚本如何?以往,DBA 使用 cron(或在 Windows 中使用 AT)作业方法运行工作,但是该方法存在两个风险:
- 如果此脚本需要登录到数据库(大部分 DBA 脚本均如此),则必须在脚本中设置用户 ID 和口令,或者以某种方式将其传递到脚本。因此,任何可以访问该脚本的用户都能够知道该口令。
- 更糟糕的是,任何可以访问服务器的用户都可以执行 ps -aef 命令来查看过程名称中的口令。
您需要防止口令曝露! 策略 可以遵循前面所述的相同策略,即在 SQL 脚本中传递口令,或者让 shell 脚本从文本文件中读取口令。该方法将避免某人在 ps -aef 输出中得知口令;不过,它不会解决某人访问脚本的问题。
在 Oracle 数据库 10g 第 1 版以及更高版本中,您可以通过数据库作业来管理此过程,这是一个极好的方法。注意,在 Oracle 数据库 10g 之前,对数据库作业的管理是通过 dbms_job 提供的程序包进行的,该程序包可以执行一个 PL/SQL 程序包、代码段或普通的 SQL,但无法执行 OS 可执行文件。在 Oracle 数据库 10g 中,新的作业管理系统是提供的程序包 dbms_scheduler(简写为 Scheduler)。除了提供一个明显改进的用户界面以外,该工具还有一个很大的优点:它甚至可以执行 OS 可执行文件 - 全部从 Oracle 数据库中执行!此功能使得实施一站式作业管理系统变得非常容易。
下面是一个例子。假设您有一个收集优化程序统计数据的 cron 作业,如下所示。 00 22 * * 6 /proprd/oracle/dbawork/utils/bin/DbAnalyze -d PROPRD1 -f DbAnalyze_PROPRD1_1.cfg 2>&1 1> /tmp/DbAnalyze1.log
您可以看到,以下作业:
- 运行一个名为 /proprd/oracle/dbawork/utils/bin/DbAnalyze -d PROPRD1 -f DbAnalyze_PROPRD1_1.cfg 的程序。
- 在每周六午夜零点 22 分运行
- 将输出写入文件 /tmp/DbAnalyze1.log
现在,为将该作业转换为一个 Scheduler 工作,您将使用下列代码段: 1 BEGIN
2 DBMS_SCHEDULER.create_job
3 (job_name => 'Dbanalyze',
4 repeat_interval => 'FREQ=WEEKLY; BYDAY=SAT BYHOUR=0 BYMINUTE=22',
5 job_type => 'EXECUTABLE',
6 job_action => '/proprd/oracle/dbawork/utils/bin/DbAnalyze -d
PROPRD1 -f DbAnalyze_PROPRD1_1.cfg',
7 enabled => TRUE,
8 comments => 'Anlyze'
9 );
10 END;
该过程的参数具有自我说明性;日历语法与英语几乎相同。(有关 Scheduler 的更多详细信息,请参阅此 OTN 文章或我撰写的图书 Oracle PL/SQLfor DBA (O'Reilly Media,2005)
既然功能强大的 cron 可供使用,为什么还要为 Scheduler 而费心呢?实际上,原因是多方面的:
- 仅当数据库可用时 Scheduler 才运行作业,这是支持以数据库为中心的作业的一大特性。您不必为检查数据库是否打开而担心。
- 各个 OS 之间的 Scheduler 语法是一致的。如果要移植,只需将代码移动到新的服务器上即可,并且只需执行一个非常简单的导出导入操作便可以启用您的计划作业。
- 与对象一样,Scheduler 作业归用户所有,这使您可以实现更好级别的权限(例如,由不同的用户执行一项作业),这一点与 cron不同,后者通常是由单个 Oracle 软件拥有者帐户使用的。
- 最值得称道的是,由于您不必在任何位置设置口令,因此并不存在意外泄露口令的风险。由于口令未存储在任何位置,因此即使 SYS 用户也无法知道用户的口令。此功能使 Scheduler 这一工具对于安全地管理 DBA(或常规用户的)的工作极具吸引力。
- 此外,您不必担心所做的更改,如用户口令更改。
可能的影响 无,只要作业与数据库相关。有一点可以肯定的是,即使当数据库不可用时,某些作业也必须运行 - 例如,将警报日志移动到不同的位置或检查数据库是否启动并正在运行的作业。这些作业应位于数据库的外部以及 cron 的内部。
操作计划
- 标识 cron 中的数据库作业。
- 确定即使在数据库关闭时仍应运行的工作(例如:每天将监听器日志移动到其他位置的作业)
- 对于其余的作业,创建 Scheduler 作业,这些作业最初通过在 CREATE_JOB 过程中声明 ENABLED=FALSE 而被禁用。
- 使用 dbms_scheduler.run_job() 过程测试作业的执行情况。
- 如果成功,则关闭 cron 作业并使用 dbms_scheduler.enable() 过程启用 Scheduler 作业。
3.4 锁定对象
背景 程序包、过程、函数、类型主体以及对象方法等编程对象包含企业的业务逻辑。对它们所做的任何改动都可能会影响总体处理逻辑,并且根据其配置情况,对生产系统的影响可能是灾难性的。
许多企业通过实施一个安全的更改-控制过程来解决此问题。在此过程中,更改首先经过讨论和审批(理想情况下在至少两个人之间进行),然后才能实施。所面临的难题是让系统自动运行,这实际上也是许多辖区和行业中的要求。 策略 这个安全的更改-控制过程可以按照以下方式运行:
- 应用程序超级拥有者(如果需要,可以是 DBA)将要更改的程序“解锁”
- 应用程序拥有者更改程序主体
- 超级拥有者锁定程序
鉴于 Oracle 数据库不包含适用于 DDL 的原生锁定机制,您将如何实施该过程?
方法之一是撤消模式拥有者的 create session 系统特权,使其始终无法登录以进行更改。取而代之的是,由有权更改指定模式的对象的应用程序拥有者进行更改。这是一个非常不错的关键数据库对象保护方法,具体体现在它支持为对象更改创建审计跟踪,而其中的跟踪可以追溯到实际用户,而非一般的模式名称。
例如,假设模式为 BANK,表名称为 ACCOUNTS。通过撤消 BANK 的 create session 权限可以禁止其登录数据库。取而代之的是,您允许拥有 create session 权限的 SCOTT 修改 ACCOUNTS。Oracle 用户 SCOTT 实际上由真人用户 Scott 拥有,任何其他人都无法访问此用户 ID。SCOTT 对 ACCOUNTS 所做的任何更改都可以直接归因于用户 Scott,从而使职责性成为安全基础架构可行性的主要组成部分。
通常情况下,要使用该方法锁定程序,您应当撤消 SCOTT 的权限。当需要更改程序时,您可以再次赋予该权限(即允许 SCOTT 更改程序),然后再次撤消该授权。
可以肯定的是,这并不是一个处理安全性的巧妙方法。很快您就会遇到问题 - 权限管理并不像“每个对象一个用户”那样简单。在典型的数据库基础架构中,数以百计的用户将获得数以千计的对象的多种类型的权限。撤消权限将消除复杂的依赖关系并带来令人头痛的管理问题。
一个可管理性更高的解决方案是使用 DDL 触发器。使用此方法,您可以根据需要建立授权,但通过 DDL 触发器控制更改。
例如,假设您想要保护模式 ARUP 中一个名为 SECURE_PKG 的程序包。您将创建一个 DDL 模式触发器,如下所示: 1 create or replace trigger no_pkg_alter
2 before ddl
3 on arup.schema
4 begin
5 if (
6 ora_dict_obj_name = 'SECURE_PKG'
7 and
8 ora_sysevent = 'CREATE'
9 )
10 then
11 raise_application_error (-20001,'Can''t Alter SECURE_PKG');
12 end if;
13 end;
14 /
在第 6 行和第 8 行中,您检查是否对该程序包进行了更改。注意,对程序包的更改是由 create or replace package 语句做出的;因此,检查的事件是 create。如果您要确保表不受更改,可以在该值中使用 alter。在第 11 行中,当程序包被更改时将产生错误。
(编辑:aniston)
|