Oracle 10g失败登陆的记录
在Oracle Database 10g中,默认的用户管理上有个小的改进,就是对默认的失败登录次数的限制,用户的PROFILE中,FAILED_LOGIN_ATTEMPTS设置口令失败尝试次数为10,如果连续进行了10次口令失败的登录尝试,用户账号将被锁定。
SQL> select * from dba_profiles where resource_name=’ FAILED_LOGIN_ATTEMPTS’; PROFILE RESOURCE_NAME RESOURCE LIMIT ---------------- -------------------------------- -------- ------------------------------ DEFAULT FAILED_LOGIN_ATTEMPTS PASSWORD 10
在一个客户环境中,曾经遇到的一个问题就是,无法定位的某个客户端,会连续通过错误的口令进行尝试,时常导致用户账号锁定。10g的这个默认改进在某些环境下的确可能存在问题,当然我们可以通过如下命令恢复之前的无限制:
alter profile default limit FAILED_LOGIN_ATTEMPTS unlimited;
可是朋友进而提出一个问题,当前失败了多少次从何处查询,如何跟踪?
这个问题开始我并不知道答案,但是我的习惯是看一下字典的底层表,用户状态等信息是通过DBA_USERS来记录展现的:
SQL> desc dba_users Name Null? Type ----------------------------------------- -------- ---------------------------- USERNAME NOT NULL VARCHAR2(30) USER_ID NOT NULL NUMBER PASSWORD VARCHAR2(30) ACCOUNT_STATUS NOT NULL VARCHAR2(32) LOCK_DATE DATE EXPIRY_DATE DATE DEFAULT_TABLESPACE NOT NULL VARCHAR2(30) TEMPORARY_TABLESPACE NOT NULL VARCHAR2(30) CREATED NOT NULL DATE PROFILE NOT NULL VARCHAR2(30) INITIAL_RSRC_CONSUMER_GROUP VARCHAR2(30) EXTERNAL_NAME VARCHAR2(4000)
使用autotrace看一下查询DBA_USERS展现的执行计划,其底层表包含PROFILE$、USER$等:
SQL> set autotrace trace explain SQL> select count(*) from dba_users; ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 78 | | 1 | SORT AGGREGATE | | 1 | 78 | |* 2 | HASH JOIN | | 13 | 1014 | |* 3 | HASH JOIN | | 13 | 975 | |* 4 | HASH JOIN | | 13 | 936 | |* 5 | HASH JOIN OUTER | | 13 | 897 | |* 6 | HASH JOIN | | 13 | 572 | |* 7 | HASH JOIN | | 13 | 546 | | 8 | MERGE JOIN CARTESIAN| | 1 | 16 | |* 9 | TABLE ACCESS FULL | PROFILE$ | 1 | 8 | | 10 | BUFFER SORT | | 1 | 8 | |* 11 | TABLE ACCESS FULL | PROFILE$ | 1 | 8 | |* 12 | TABLE ACCESS FULL | USER$ | 18 | 468 | | 13 | TABLE ACCESS FULL | PROFNAME$ | 1 | 2 | |* 14 | TABLE ACCESS FULL | RESOURCE_GROUP_MAPPING$ | 2 | 50 | | 15 | TABLE ACCESS FULL | USER_ASTATUS_MAP | 9 | 27 | | 16 | TABLE ACCESS FULL | TS$ | 23 | 69 | | 17 | TABLE ACCESS FULL | TS$ | 23 | 69 | -------------------------------------------------------------------------------
查看底层表USER$的字段,其中LCOUNT字段立刻引起了我们的注意:
SQL> desc user$ Name Null? Type ----------------------------- -------- -------------------- USER# NOT NULL NUMBER NAME NOT NULL VARCHAR2(30) TYPE# NOT NULL NUMBER PASSWORD VARCHAR2(30) DATATS# NOT NULL NUMBER TEMPTS# NOT NULL NUMBER DEFROLE NOT NULL NUMBER DEFGRP# NUMBER DEFGRP_SEQ# NUMBER ASTATUS NOT NULL NUMBER LCOUNT NOT NULL NUMBER 。。。。。。。。
找个用户测试一下,可以发现Oracle数据库正是通过这个字段来记录登录失败的次数的(一旦成功登录之后,该计数会被清零):
SQL> select name,lcount from user$ where name='EYGLEE'; NAME LCOUNT ------------------------------ ---------- EYGLEE 0 SQL> connect eyglee/ee ERROR: ORA-01017: invalid username/password; logon denied Warning: You are no longer connected to ORACLE. SQL> connect / as sysdba Connected. SQL> select name,lcount from user$ where name='EYGLEE'; NAME LCOUNT ------------------------------ ---------- EYGLEE 1
进一步,我们可以通过sql.bsq文件来确认一下,这个文件提示lcount正是失败的登录尝试计数(count of failed login attempts):
图:USER$的数据结构
虽然我们可以从数据字典中获得很多知识,但是切记不要轻易修改数据字典的内容,数据字典是数据库的核心数据存储地,修改其内容很容易导致数据库崩溃和无法启动。
Oracle 11g口令大小写的区分
在Oracle 11g的第一版中存在如下一个安全设置的步骤,在这个步骤中,缺省的选择是使用11g的安全设置,这个设置包含新的口令规则和审计启用,另外一个可选项是使用11g之前的设置;这里的改变主要包括口令的大小写区分等。
这个页面在Oracle Database 11gR2中被去除,相应的设置变成了默认缺省项。
在Oracle 11g 之前用户口令是不区分大小写的,从11g开始,口令也可以区分大小写。大小写的区分是因为Oracle采用了160 bit SHA-1哈希算法校验,校验的信息记录在USER$.SPARE4中:
SQL> select name,password,spare4 from user$ where name='EYGLE'; NAME PASSWORD SPARE4 ---------- ---------------- -------------------------------------------------------------- EYGLE 887B1FDEF9051C7A S:1345AE7E05AB4ACAF3136006C82311800898F56C05293E45A05A4E290814
以下简单测试说明了这一增强:
SQL> connect scott/tiger 已连接。 SQL> alter user scott identified by TIGER; 用户已更改。 SQL> connect scott/tiger ERROR: ORA-01017: 用户名/口令无效; 登录被拒绝 警告: 您不再连接到 ORACLE。 SQL> connect scott/TIGER 已连接。
这一特性可以通过初始化参数SEC_CASE_SENSITIVE_LOGON 控制,修改该参数为FALSE将取消大小写的区分:
SQL> alter system set sec_case_sensitive_logon = false; 系统已更改。 SQL> connect scott/tiger 已连接。 SQL> connect scott/TIGER 已连接。
通常建议用户启用这一特性,增强口令安全。在Oracle11gR2中,创建数据库时如果给定的口令过于简单,就会出现关于口令安全规则的告警:
图:Oracle 11gR2 关于口令安全的告警
Oracle 11g缺省口令的跟踪
在Oracle 11g中,数据库中还增加了一个DBA_USERS_WITH_DEFPWD视图用于显示那些具有缺省口令的用户,以下是一个查询输出(这些帐号多数处于锁定状态):
SQL> select * from DBA_USERS_WITH_DEFPWD; USERNAME ------------------------------ DIP XS$NULL MDSYS OUTLN OLAPSYS OWBSYS ORACLE_OCM EXFSYS SCOTT DBSNMP ORDSYS
检查这个视图的创建语句,可以发现实际上Oracle增加了一个default_pwd$表用于记录用户的缺省口令,再通过user$联合进行u.password = dp.pwd_verifier的等值判断,过滤出那些具有缺省口令的用户:
SQL> set long 12000 SQL> select text from dba_views where view_name='DBA_USERS_WITH_DEFPWD'; TEXT ------------------------------------------------------------------------ SELECT DISTINCT u.name FROM SYS.user$ u, SYS.default_pwd$ dp WHERE (u.type# = 1 AND bitand(u.astatus, 16) = 16 ) OR (u.type# = 1 AND u.password = dp.pwd_verifier AND u.name = dp.user_name AND dp.pv_type = 0)
DEFAULT_PWD$表记录的内容如下:
SQL> select * from DEFAULT_PWD$ where rownum <10; USER_NAME PWD_VERIFIER PV_TYPE ------------------------------ ------------------------------ ---------- AASH 9B52488370BB3D77 0 ABA1 30FD307004F350DE 0 ABM D0F2982F121C7840 0 AD_MONITOR 54F0C83F51B03F49 0 ADAMS 72CDEF4A3483F60D 0 ADS D23F0F5D871EB69F 0 ADSEUL_US 4953B2EB6FCB4339 0 AHL 7910AE63C9F7EEEE 0 AHM 33C2E27CF5E401A4 0
除此之外, DBA_USERS 视图对口令的管理也发生了变化,原有的PASSWORD列不再显示口令(在底层USER$表中仍然存在),新增加了 PASSWORD_VERSIONS 列用于显示口令管理版本(10G 11G指用户从10G升级或在11G中创建)
SQL> select username,password,password_versions from dba_users where rownum <7; USERNAME PASSWORD PASSWORD ------------------------------ ------------------------------ -------- SYS 10G 11G SYSTEM 10G 11G OUTLN 10G 11G MGMT_VIEW 10G 11G FLOWS_FILES 10G 11G MDSYS 10G 11G
这里的口令隐藏是通过在DBA_USERS视图中增加了一个如下Decode判断实现的:
decode(u.password, 'GLOBAL', u.password,'EXTERNAL', u.password,NULL)
通过DBA_VIEWS.TEXT字段客户获得关于视图定义的完整子句。
Oracle口令的复杂度校验
当定义或更改数据库用户口令时,为了避免弱口令的风险,Oracle数据库允许对口令进行强化校验,这个功能缺省未开启,需要运行$ORACLE_HOME/rdbms/admin/utlpwdmg.sql脚本来创建启用。
这个脚本从Oracle9i开始既已存在,不过由于数据库用户口令的更改是个影响极大、较为复杂的过程,所以很少有用户对口令进行复杂校验。
通过这个脚本来了解一下Oracle对于安全的考量和增强,以下是Oracle 11gR2版本的脚本文件示例。脚本开头部分说明了其作用:
Rem NAME Rem utlpwdmg.sql - script for Default Password Resource Limits Rem Rem DESCRIPTION Rem This is a script for enabling the password management features Rem by setting the default password resource limits. Rem Rem NOTES Rem This file contains a function for minimum checking of password Rem complexity. This is more of a sample function that the customer Rem can use to develop the function for actual complexity checks that the Rem customer wants to make on the new password.
脚本创建一个函数verify_function_11G用于口令校验,然后修改用户缺省的Profile,更改口令检验方式:
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 180 -----------------口令有效期为180天
PASSWORD_GRACE_TIME 7 ------------------口令宽限期为7天
PASSWORD_REUSE_TIME UNLIMITED ----口令可重用时间无限制
PASSWORD_REUSE_MAX UNLIMITED ----口令重用之前口令需要改变的次数
FAILED_LOGIN_ATTEMPTS 10 -------------用于指定连续登陆的最大失败次数
PASSWORD_LOCK_TIME 1 ------------------用于指定帐户被锁定的天数
PASSWORD_VERIFY_FUNCTION verify_function_11G;
以上是11g中的参数设置,之前版本的参数限制如下,可以相互参考,设置适合自己数据库的参数限制:
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 60
PASSWORD_GRACE_TIME 10
PASSWORD_REUSE_TIME 1800
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 3
PASSWORD_LOCK_TIME 1/1440
PASSWORD_VERIFY_FUNCTION verify_function;
运行之后:
SQL> @?/rdbms/admin/utlpwdmg.sql 函数已创建。 配置文件已更改 函数已创建。 SQL> select username,profile from dba_users where username='EYGLE'; USERNAME PROFILE ------------------------------ ------------------------------ EYGLE DEFAULT SQL> select * from dba_profiles where profile='DEFAULT'; PROFILE RESOURCE_NAME RESOURCE LIMIT ---------- -------------------------------- -------- ---------------------- DEFAULT COMPOSITE_LIMIT KERNEL UNLIMITED DEFAULT SESSIONS_PER_USER KERNEL UNLIMITED DEFAULT CPU_PER_SESSION KERNEL UNLIMITED DEFAULT CPU_PER_CALL KERNEL UNLIMITED DEFAULT LOGICAL_READS_PER_SESSION KERNEL UNLIMITED DEFAULT LOGICAL_READS_PER_CALL KERNEL UNLIMITED DEFAULT IDLE_TIME KERNEL UNLIMITED DEFAULT CONNECT_TIME KERNEL UNLIMITED DEFAULT PRIVATE_SGA KERNEL UNLIMITED DEFAULT FAILED_LOGIN_ATTEMPTS PASSWORD 10 DEFAULT PASSWORD_LIFE_TIME PASSWORD 180 DEFAULT PASSWORD_REUSE_TIME PASSWORD UNLIMITED DEFAULT PASSWORD_REUSE_MAX PASSWORD UNLIMITED DEFAULT PASSWORD_VERIFY_FUNCTION PASSWORD VERIFY_FUNCTION_11G DEFAULT PASSWORD_LOCK_TIME PASSWORD 1 DEFAULT PASSWORD_GRACE_TIME PASSWORD 7
但是需要注意,不要为数据库的几个重要缺省用户修改口令规则,否则可能会引发麻烦,这些用户包括SYS, SYSMAN和 DBSNMP等。
变更了缺省的PROFILE之后,此时修改用户口令,将会受到VERIFY_FUNCTION_11G的约束,如果口令不符合要求,将会返回提示:
SQL> connect eygle/eygle 已连接。 SQL> password 更改 EYGLE 的口令 旧口令: 新口令: 重新键入新口令: ERROR: ORA-28003: 指定口令的口令验证失败 ORA-20001: Password length less than 8 口令未更改 SQL> password 更改 EYGLE 的口令 旧口令: 新口令: 重新键入新口令: ERROR: ORA-28003: 指定口令的口令验证失败 ORA-20008: Password must contain at least one digit, one character 口令未更改
VERIFY_FUNCTION_11G缺省的设定如下规则限制用户的口令:
1. 口令至少八个字符
2. 口令不能与用户名称相同,也不能由用户名加数字或用户名反转构成
3. 口令必须与数据库名称不同,也不能由数据库名加简单数字构成
4. 口令字符串需要包含至少一个字母和一个数字字符
5. 与之前的口令至少有三个字符不同
一般建议用户根据这个缺省的函数,进行修改构建满足自己需要的安全检验机制。
随着安全越来越被用户重视,我们通常建议用户启用口令安全校验措施,增加复杂性的好处是带来安全。