用户名、密码是我们最常见的安全验证策略方法,也是我们在各种应用系统软件中采用的最多的安全保护策略。对Oracle而言,以最大限度保护系统数据安全,是不可推卸的天然职责。
从最早版本到今天,Oracle在用户名和密码安全策略方面不断的加以改进,比如,进入11g之后,Default Profile要求定期进行用户密码修改操作,用户密码加密算法强化,以及对dba_users等数据字典视图进行优化改进。今天我们要讨论的是一种Oracle的另一种验证策略——OS验证策略。
这里,我们要进行一定澄清。最常见的OS验证策略,发生在Oracle服务器端的机器上。突出的表现是:如果我们通过了操作系统层面验证,也就是登录了服务器本机(Remote Desktop或者SecurCRT),Oracle就认为当前用户已经可以通过认证,不需要额外的数据库验证。当然,这要求操作系统用户归属在系统特定用户组,如Linux中的oinstall、dba。比如我们经常启动关闭服务器使用的conn /方式,就是这个类型登录验证方法。注意:通过在sqlnet.ora中参数的配置,我们是可以关闭这个特性的。
普通的OS验证策略两个特点:一个是服务器本地生效,客户端匿名登录无效。另一个只能登录为管理员sys,不能其他用户。那么,有没有方法实现客户端远程匿名登录,而且实现非sys用户呢?本篇我们就来介绍这个方法。
1、实验环境介绍
我们实验环境为Oracle 11g,具体版本为11.2.0.4。服务器为Linux版本。
SQL> select * from v$version;
BANNER
---------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE11.2.0.4.0Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
与本实验相关的参数保持默认状态。
SQL> show parameter os
NAMETYPEVALUE
------------------------------------ ----------- ------------------------------
db_lost_write_protectstringNONE
diagnostic_deststring/u01/app
optimizer_index_cost_adjinteger100
os_authent_prefixstringops$
os_rolesbooleanFALSE
remote_os_authentbooleanFALSE
remote_os_rolesbooleanFALSE
timed_os_statisticsinteger0
默认情况下,我们只能在服务器端实现匿名登录,登录之后直接以最高权限sys的角色出现。
SQL> conn / as sysdba
Connected.
SQL> show user
USER is "SYS"
不添加as sysdba登录过程是不允许的。
SQL> conn /
ERROR:
ORA-01017: invalid username/password; logon denied
下面我们来讨论如何进行OS层面验证。
2、服务器端OS验证配置
Oracle的OS层面验证,最直接的关联参数就是os_authent_prefix,默认取值为ops$。这种技术是很简单的,是建立在操作系统用户名与数据库用户名之间的映射规则上。
Oracle规定,如果尝试连接数据库的操作系统用户名添加参数os_authent_prefix作为前缀之后,与数据库某一个特定用户名schema相同,那么就可以实现OS验证配置。注意:这个规则是在服务器端成立的。比如:如果当前连接的操作系统名为oracle,os_authent_prefix为ops$,如果此时数据库中包括一个为ops$oracle的用户,是可以在服务器端进行匿名登录的。
下面进行测试,当前Linux服务器端OS用户名为oracle,也是oinstall和dba组成员。
[oracle@localhost ~]$ id
uid=500(oracle) gid=500(oinstall) groups=500(oinstall),501(dba),502(oper)context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
创建用户ops$oracle,授予一定权限。
SQL> create user ops$oracle identified by oracle;
User created.
SQL> grant connect, resource to ops$oracle;
Grant succeeded.
这样conn /后不带as sysdba登录就允许通过了。
SQL> conn /
Connected.
SQL> show user
USER is "OPS$ORACLE"
如果添加了as sysdba,匿名管理员登录同样成立。
SQL> conn / as sysdba
Connected.
SQL> show user
USER is "SYS"
这个规则在服务器端还是问题不大,在现实环境中实际意义也不是很大。但是,这个特性势必会引起一个想法:匿名远程登录是否可以实现?
3、匿名OS验证远程登录
在之前笔者的文章中,我们讨论过什么是“远程登录”。结论是:对Oracle而言,只要通过监听器程序的过程,Oracle都会将其作为远程登录。而不是去探究登录动作是不是服务器端发生。要经过监听器程序,最直接的就是登录中加入@地址标记符。
我们首先在服务器端进行试验,其上已经有sicspcdb的本地连接命名。
[oracle@localhost ~]$ tnsping sicspcdb
TNS Ping Utility for Linux: Version 11.2.0.4.0 - Production on 14-JUL-2014 17:47:08
Copyright (c) 1997, 2013, Oracle.All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = sicspcdb)))
OK (0 msec)
测试服务器端OS匿名验证。
SQL> conn /@sicspcdb
ERROR:
ORA-01017: invalid username/password; logon denied
SQL> conn /@sicspcdb as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied
远程匿名登录,Oracle默认是关闭的。这个在实际生产环境中非常有必要,远程客户端对于Oracle而言是不安全可靠的。如果希望开启,需要调整参数remote_os_authent。
SQL> alter system set remote_os_authent=true;
alter system set remote_os_authent=true
*
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified
该参数需要重启数据库。
SQL> alter system set remote_os_authent=true scope=spfile;
System altered.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
ORACLE instance started.
Total System Global Area 2.0911E+10 bytes
Fixed Size2262368 bytes
Variable Size1.1677E+10 bytes
Database Buffers9193914368 bytes
Redo Buffers38170624 bytes
Database mounted.
Database opened.
注意:我们修改参数之后,重启Oracle报提示过期参数出现在实例启动环节。这个现象我们注意下来,之后讨论!
Os参数修改成功。
SQL> show parameter os
NAMETYPEVALUE
------------------------------------ ----------- ------------------------------
(篇幅原因,有省略……)
os_authent_prefixstringops$
os_rolesbooleanFALSE
remote_os_authentbooleanTRUE
remote_os_rolesbooleanFALSE
timed_os_statisticsinteger0
为了后续操作,生成一份pfile。
SQL> create pfile from spfile;
File created.
此时,在Linux服务器端OS匿名登录成功。
SQL> conn /--服务器本地登录成功
Connected.
SQL> conn /@sicspcdb –-服务器远程匿名登录成功
Connected.
SQL> show user
USER is "OPS$ORACLE"
SQL> conn /@sicspcdb as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied –sys远程匿名登录失败!
下面我们在windows客户端上进行测试,看远程客户端OS匿名登录是否成功。Windows操作系统用户名为admin,需要在数据库中进行额外配置。
SQL> create user ops$admin identified by oracle;
User created.
SQL> grant connect, resource to ops$admin;
Grant succeeded.
在windows本地测试:
--本地TNS名称验证
C:\Users\admin>tnsping sicspcdb_linux_bk
TNS Ping Utility for 64-bit Windows: Version 11.2.0.4.0 - Production on 14-7月-
2014 18:04:25
Copyright (c) 1997, 2013, Oracle.All rights reserved.
已使用的参数文件:
D:\app\admin\product\11.2.0\dbhome_1\network\admin\sqlnet.ora
已使用TNSNAMES适配器来解析别名
尝试连接(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.1
6.19.2)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = sicspcdb)))
OK (10毫秒)
登录测试。
C:\Users\admin>sqlplus /nolog
SQL*Plus: Release 11.2.0.4.0 Production on星期一7月14 18:04:45 2014
Copyright (c) 1982, 2013, Oracle.All rights reserved.
SQL> conn /@sicspcdb_linux_bk
已连接。
SQL> show user
USER为"OPS$ADMIN"
实验成功!通过参数remote_os_authent的开启,可以帮助我们实现客户端的匿名登录。
4、匿名登录与安全
随着我们日常生活信息化,越来越多的系统出现在我们身边,记住各种系统的用户名密码开始成为生活工作的负担。所以,类似于单点登录的技术会有很大的发展前景。但是,对于数据库而言,OS匿名登录还是存在很大的风险。
Oracle数据库连接验证包括几个要素:服务器IP地址、服务名、连接端口和用户名密码信息。从信息公开角度看,服务器IP地址、服务名和连接端口是没有什么秘密而言的。真正能够起到数据保护的,也就是用户名和密码信息。如果普遍采用OS匿名登录,特别是客户端普遍使用,只要操作系统创建一个特定的用户,就可以直接登录,显然是危险的。
回到我们重启数据库过程中,报错过期参数使用的情况。我们打开生成的pfile文件,可以看到设置的remote_os_authent参数。
[oracle@localhost dbs]$ cat initsicspcdb.ora
sicspcdb.__db_cache_size=9193914368
*.processes=1000
*.remote_login_passwordfile='EXCLUSIVE'
*.remote_os_authent=TRUE
*.sessions=1105
*.undo_tablespace='UNDOTBS1'
使用这个pfile启动数据库,可以报错更加清晰。
SQL> startup pfile=initsicspcdb.ora
ORA-32006: REMOTE_OS_AUTHENT initialization parameter has been deprecated
Remote_os_authent已经被认为过期,Oracle甚至不推荐我们再使用这个参数了。在pfile中删除参数,重新启动数据库。
*.remote_login_passwordfile='EXCLUSIVE'
*.remote_os_authent=FALSE
*.sessions=1105
*.undo_tablespace='UNDOTBS1'
--剔除之后
Database dismounted.
ORACLE instance shut down.
SQL> startup pfile=initsicspcdb.ora
ORACLE instance started.
Total System Global Area 2.0911E+10 bytes
Fixed Size2262368 bytes
Variable Size1.1677E+10 bytes
Database Buffers9193914368 bytes
从这个现象,我们可以猜测:Oracle也不推荐使用OS验证。
5、结论
OS匿名验证这个特性出现的很早,是早期Oracle发展的一个方向。近些年的版本中,这个特性没有过多的发展,说明Oracle在这个方面已经不再过多延伸了。在笔者之前的文章中,也介绍过借助Oracle客户端wallet特性实现的匿名登录,两者原理不同,安全性差异也有千差万别。