重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
数据库安全问题一直是人们关注的焦点之一,我们知道一个企业或者机构的数据库如果遭到黑客的攻击,而这些数据库又保存着非常重要的数据,象银行、通信等数据库,后果将不堪设想。oracle数据库使用了多种手段来保证数据库的安全性,如密码,角色,权限等等,今天我们来详细的来阐述一下关于oracle的密码问题,当然我们今天来详细说的并不是oracle的安全密码机制如何的强大等等,恰恰相反我们需要说明的是当我们在oracle密码过期后如何在不修改密码的情况下,使密码重新有效。
站在用户的角度思考问题,与客户深入沟通,找到容县网站设计与容县网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站设计、网站建设、企业官网、英文网站、手机端网站、网站推广、空间域名、网站空间、企业邮箱。业务覆盖容县地区。
在介绍前我们先来说一个案例,某客户数据库做安全加固,针对profile修改了部分password的安全机制,其中最重要的一点就是设置了PASSWORD_LIFE_TIME(该参数设定密码过期时间)这一个参数,而当该参数设置完后,客户又没有根据设定的安全机制指定一个良好的人工密码周期性管理策略,随着PASSWORD_LIFE_TIME参数所设定的时间到期后,数据库将该用户locked,导致业务无法正常连接,从理论上来说,密码既然过期了,那么重置密码是唯一的手段,但是从一定程度上来说,重置密码意味着大量的中间件需要去修改,对于业务逻辑不熟悉的人来说,还是存在必然的风险,检查后发现客户并没有设置PASSWORD_REUSE_TIME(该参数设定为相同密码重用时间),既然该参数并没有设置,那么我们可以考虑通过一个临时密码来作为中间密码,通过中间密码进一步重新设置原密码。但是这时候又一个问题出现了,客户并不知道该业务用户密码。这又从一定程度上给问题的解决造成了麻烦。本节通过一个较为巧妙的方法来重置oracle的密码。
n 概念普及
在详细说明本节内容的情况下,需要普及一些小的知识点,oracle在对于密码有效期等问题的管理上通过profile文件来进行管理。并默认一个default的profile文件,在oracle 9i以及以前版本,oracle对于默认的default profile文件参数值均为UNLIMITED,在10g版本中,将FAILED_LOGIN_ATTEMPTS的值默认设置为10次,也就是说在连续10次输入错误密码后,oracle将锁定该用户,直到用户被解锁为止。从11g开始,oracle对密码文件的管理策略增加了很多,很多之前被设置了UNLIMITED的参数,在11g中都定义了相应的值,虽然这一新特性增加了oracle密码的安全机制,但是也从一定程度上对我们管理产生影响。首先我们来说明一下oracle的profile 中关于密码这一部分的内容。(该默认的profile取自oracle11g环境)
SQL> select * from dba_profiles where profile='DEFAULT' and RESOURCE_NAME like 'PASSWORD_%'; PROFILE RESOURCE_NAME RESOURCE LIMIT --------- --------------------------------- ---------- DEFAULT PASSWORD_LIFE_TIME PASSWORD 180 DEFAULT PASSWORD_REUSE_TIME PASSWORD UNLIMITED DEFAULT PASSWORD_REUSE_MAX PASSWORD UNLIMITED DEFAULT PASSWORD_VERIFY_FUNCTION PASSWORD NULL DEFAULT PASSWORD_LOCK_TIME PASSWORD 1 DEFAULT PASSWORD_GRACE_TIME PASSWORD 7 |
详细解释一下以上参数值:
PASSWORD_LIFE_TIME 180 --口令的生命周期,超过这段时间口令可能会自动过期,是否过期要看是否设定了PASSWORD_GRACE_TIME
PASSWORD_GRACE_TIME 7 --接着PASSWORD_LIFE_TIME特性,如果PASSWORD_LIFE_TIME的期限已到,那么PASSWORD_GRACE_TIME 的设置是对口令生命周期的一个grace(宽限或者延续),口令到期之后,继续可以使用的天数,在这段时间内如果我们登录系统,会有提示,提示系统在几天内过期
PASSWORD_REUSE_TIME UNLIMITED --这个特性限制口令在多少天内不能重复使用,默认值为UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED --这个特性是针对PASSWORD_REUSE_TIME的,说明要想在PASSWORD_REUSE_TIME这个参数指定的时间内重复使用当前口令,那么至少需要修改过口令的次数(修改过的口令当然肯定需要和当前口令不同,因为毕竟还有PASSWORD_REUSE_TIME 特性的限制)
FAILED_LOGIN_ATTEMPTS 10 --这个比较好理解,不知道口令的话尝试登录的次数,达到这个次数之后账户被自动锁定
PASSWORD_LOCK_TIME 1 --接着FAILED_LOGIN_ATTEMPTS参数,口令被自动锁定的时间,达到这个时间之后,下次登录时系统自动解除对这个账户的锁定
以上即为oracle对于profile中密码管理的一些参数解释。
接下来我们来说明一下oracle中关于用户锁定的状态
SQL> select username,account_status,profile from dba_users;
USERNAME ACCOUNT_STATUS PROFILE -------------------------------------------- SYSTEM OPEN DEFAULT SYS OPEN DEFAULT TEST3 OPEN DEFAULT SCOTT OPEN DEFAULT TEST2 EXPIRED(GRACE) PROFILE2 TEST EXPIRED(GRACE) DEFAULT MGMT_VIEW EXPIRED & LOCKED DEFAULT |
ORACLE数据库用户有多种状态,可查看视图USER_ASTATUS_MAP。
SQL>select * from user_astatus_map; STATUS# STATUS -------- ------------------------------ 0 OPEN 1 EXPIRED 2 EXPIRED(GRACE) 4 LOCKED(TIMED) 8 LOCKED 5 EXPIRED & LOCKED(TIMED) 6 EXPIRED(GRACE) & LOCKED(TIMED) 9 EXPIRED & LOCKED 10 EXPIRED(GRACE) & LOCKED |
可以看到oracle一共提供了9种状态,而九种状态可分为两类:1.基本状态;2.组合状态。
前五种是基本状态:0 OPEN、1 EXPIRED、2 EXPIRED(GRACE)、4 LOCKED(TIMED)、8 LOCKED。
后四种是基本状态:5 EXPIRED & LOCKED(TIMED)、6 EXPIRED(GRACE) & LOCKED(TIMED)、9 EXPIRED & LOCKED、10 EXPIRED(GRACE) & LOCKED。
后四种的组合状态可通过状态号STATUS#获得其状态的两个组合,对于我们常态管理来说我们只需要掌握前面5种即可,以上客户所发生的问题就是由于对于profile的设置导致的密码失效的问题。
巧解密码过期
在上述的客户案例中,安全加固措施固然是好的,但是没有客观考虑到后期密码维护是一个潜在的问题,而在oracle11G中PASSWORD_LIFE_TIME参数从很大一定程度上也会造成上述客户的问题,DBA如果不清楚这一特性很容易造成密码锁定这个问题,当造成了这一问题后如何解决成了一个很大的问题。
在10g或者11g环境中,如果profiles的密码参数被设置后,会导致密码在规定的时间内过期,锁定等。此时如果我们继续去连接,如果状态变成EXPIRED或者EXPIRED(GRACE)那么当我们连接后,会提示需要重新设定新的密码,并且该会话无法连入数据库,此时如果我们知道该用户的密码,那么DBA只需要手工干预一下,重新设定该密码即可。
在10G环境中,我们仔细查看dba_users这张视图,对应的PASSWORD这个字段,其实该字段即为我们设置的密码的HASH值,当我们的密码过期或者用户被锁定后,可以通过该字段来巧妙的规避一下该特性。
查看用户信息(10G版本)
SQL> select username,account_status,password from dba_users where username like 'TEST%';
USERNAME ACCOUNT_STATUS PASSWORD ------------ ---------------- ------------------ TEST2 OPEN 3C0731F39486287E TEST1 OPEN C04FB3810DDE34AE |
我们可以看到,以上的密码进过加密处理后显示为一串无序的HASH值。而在11G开始,oracle为了凸显密码安全性,将dba_users中的password这一列不再做显示
查看用户信息(11G版本)
SQL> select username,account_status,password from dba_users where username like '%TEST%';
USERNAME ACCOUNT_STATUS PASSWORD ------------------ ---------------- ----------- TEST OPEN TESTYING3 OPEN TEST2 EXPIRED TEST3 OPEN
6 rows selected. |
可以看到,从11G开始,oracle将password这一列给隐藏了
注:Oracle11g在用户安全性方面的加强,不仅仅是密码的隐藏,还包括
1.密码区分大小写,初始化参数sec_case_sensitive_logon 2.密码复杂性检查,通过utlpwdmg.sql文件创建复杂性检查函数verify_function_11G 3. 强度更高的Hash加密算法 |
当我们的用户密码过期并且被锁定后,再次登录将会产生报错:用户被锁定,
如下用户:
SQL> select username,account_status,password,profile from dba_users where username='MDSYS'; USERNAME ACCOUNT_STATUS PASSWORD PROFIL ---------- ------------------------------------------------ MDSYS EXPIRED & LOCKED 72979A94BAD2AF80 DEFAULT
SQL> select username,account_status,password,profile from dba_users where username='TEST1';
USERNAME ACCOUNT_STATUS PASSWORD PROFILE ---------- --------------------------------- ------- TEST1 LOCKED C04FB3810DDE34AE DEFAULT |
注意LOCKED和EXPIRED & LOCKED是两个不同的概念,对于LOCKED状态是由于连续的输错密码达到FAILED_LOGIN_ATTEMPTS指定的次数二造成的,对于该种故障,我们只需要简单的给与用户解锁即可,如下:
SQL> alter user test1 account unlock; User altered.
SQL> select username,account_status,password,profile from dba_users where username='TEST1'; USERNAME ACCOUNT_STATUS PASSWORD PROFILE ---------- --------------------------------- ------- TEST1 OPEN C04FB3810DDE34AE DEFAULT |
但是对于EXPIRED & LOCKED状态,这是由于PASSWORD_LIFE_TIME参数导致用户密码过期而造成的锁定,单一的解锁命令无法解决该问题,此处还涉及到PASSWORD_LIFE_TIME参数造成的密码修改问题。如下:
SQL> select username,account_status,password,profile from dba_users where username='MDSYS'; USERNAME ACCOUNT_STATUS PASSWORD PROFILE ---------- ------------------------------------------------ MDSYS EXPIRED & LOCKED 72979A94BAD2AF80 DEFAULT SQL> conn mdsys/mdsys ERROR: ORA-28000: the account is locked Warning: You are no longer connected to ORACLE.
解锁用户: SQL> conn / as sysdba Connected. SQL> alter user dmsys account unlock; User altered. SQL> conn dmsys/dmsys ERROR: ORA-28001: the password has expired
Changing password for dmsys New password: 提示需要输入新密码 此时我们查看用户状态: SQL> select username,account_status,password,profile from dba_users where username='MDSYS'; USERNAME ACCOUNT_STATUS PASSWORD PROFILE ---------- ---------------- ------------------ --------- MDSYS EXPIRED 72979A94BAD2AF80 DEFAULT |
我们从上面的实验过程看到,虽然我们将用户解锁,但是用户的状态仅仅从EXPIRED & LOCKED转为EXPIRED,并没有正常的OPEN,从新连接用户提示输入新密码。
此处就产生一个问题,可以想象一下,当提示我们输入新密码时,我们势必需要输入生产用户的原密码,否则将造成业务中间件的密码与修改的密码不一致。如果此时我们不知道原密码,势必会造成一定的麻烦。此时我们就需要dba_users视图中的password字段。Password字段虽然已经经过oracle的hash运算并加密(oracle密码采用用户名+密码的组合进行HASH加密),但是我们并不是需要知道该密码是什么,只是需要利用该字段HASH值来成功的解锁用户。
对于一个用户赋新的密码,相信大家都很了解:
alter user username identified by password
那么我们就可以利用password的hash值进行巧妙的解锁,如下:
SQL> alter user dmsys identified by values 'BFBA5A553FD9E28A'; User altered.
SQL> select username,account_status,password,profile from dba_users where username='MDSYS'; USERNAME ACCOUNT_STATUS PASSWORD PROFILE ---------- ---------------- ----------------- --------- MDSYS OPEN 72979A94BAD2AF80 DEFAULT
SQL> conn dmsys/dmsys Connected. SQL> |
可以看到,虽然我们不知道该用户的密码,但是我们可以在通过password的HASH值来重置该密码。而在11G中,oracle为了提高安全性能,将DBA_USERS.password中的值不做显示,默认为空。如下:
SQL> select username,account_status,password from dba_users;
USERNAME ACCOUNT_STATUS PASSWORD ---------------------------- ---------- SYS OPEN WMSYS OPEN TESTYING3 OPEN TESTYING OPEN |
在11G环境中,我们可以通过USER$基表中查询得到该值,如下:
SQL> select USER#,name,PASSWORD from user$ where name like 'TEST%'; USER# NAME PASSWORD ---------- --------- --------------------- 85 TEST 48724AE7C369325F 86 TEST2 3C0731F39486287E 87 TEST3 47B23A1E17F2D107 6 rows selected. |
运用同样的命令和方法,我们就可以解锁密码过期而导致的用户锁定。
技术结论
通过以上的方法,我们可以在不知晓用户名密码的情况下,比较巧妙的解锁由于密码过期而导致的用户锁定的情况,虽然我们在上述方法中通过HASH值解锁了用户,但是无论从安全方面抑或是从数据库的持续稳定运行方面考虑,我们都建议用户采用安全合理的密码管理机制,杜绝一切可能的隐患才是作为一名DBA所必须要做到的,在保障数据库安全的同时,维持数据库的正常稳定运行。
------------------------------------------------------------------------------------
<版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!>
原博客地址:http://blog.itpub.net/23732248/
原作者:应以峰 (frank-ying)
-------------------------------------------------------------------------------------