Archive for the ‘security’ tag
Listener Password in Oracle 10g
在Google上搜索“监听 安全 oracle”,一堆《实例讲解Oracle监听口令及监听器安全》的文章,都是copy+paste自eygle的这篇《Oracle的监听口令及监听器安全》,eygle的测试环境是本地的10.2.0.3客户端加远程9.2.0.4数据库。
如果服务器端数据库版本在Oracle9i以后,设置监听密码的情况则有一些变化。
在Metalink Note 260986.1中,可以看到:
In Oracle 10, the TNSListener is secure out of the box and there should not be a need to set a listener password as in older versions of the Oracle listener.
Oracle10g以后,设置Listener密码已经不是安全检查的必要条件了,因为默认在10g里面除了启动监听的用户之外,其它用户都无法停止Listener(还有另外一些lsnrctl的命令也同样被禁止了,比如trace, reload等),即使Listener没有设置密码。
在默认情况下,启动Listener或者使用lsnrctl status命令查看监听状态,可以看到:
Security ON: Password OR LOCAL OS Authentication
这表明Listener的安全机制使用了Password方式或者Local OS Authentication方式,在这种状态下,即使是设置了监听密码,对于启动监听的user来说,也仍然是不需要任何密码就可以停止监听的。
如果我们想去除自Oracle10g之后的这种新安全机制,那么需要在listener.ora文件中添加:
LOCAL_OS_AUTHENTICATION_[listener name] = OFF
重新启动Listener之后,将会只看到:
Security ON: Password这就又回复到了Oracle9i时的状态,只要有密码存在,无论是谁尝试停止监听都会被要求set password。
D:\Temp>lsnrctl LSNRCTL for 32-bit Windows: Version 11.1.0.7.0 - Production on 20-MAY-2009 11:15:41 Copyright (c) 1991, 2008, Oracle. All rights reserved. Welcome to LSNRCTL, type "help" for information. LSNRCTL> status Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521))) TNS-01169: The listener has not recognized the password LSNRCTL> stop Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521))) TNS-01169: The listener has not recognized the password LSNRCTL> set password Password: The command completed successfully LSNRCTL> status Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for 32-bit Windows: Version 11.1.0.7.0 - Production Start Date 20-MAY-2009 11:14:22 Uptime 0 days 0 hr. 1 min. 34 sec Trace Level off Security ON: Password SNMP OFF Listener Parameter File D:\oracle\product\11.1.0\db_1\network\admin\listener.ora Listener Log File d:\oracle\diag\tnslsnr\kamus-laptop\listener\alert\log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=kamus-laptop)(PORT=1521))) Services Summary... Service "orcl11g" has 1 instance(s). Instance "orcl11g", status READY, has 1 handler(s) for this service... Service "orcl11g_XPT" has 1 instance(s). Instance "orcl11g", status READY, has 1 handler(s) for this service... The command completed successfully LSNRCTL> stop Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521))) The command completed successfully LSNRCTL>
How to Prevent DBA User From Logining Database Without Password
我们知道如果某个操作系统用户属于dba组,那么登录了这个用户之后,不再需要任何密码就能以SYS用户登录到数据库中,在产品环境中,这无疑是一个严重的安全漏洞。
kamus@desktop:~$ whoami kamus kamus@desktop:~$ sqlplus / as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 17:56:58 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to an idle instance. SQL> show user USER is "SYS" SQL> exit Disconnected kamus@desktop:~$ sqlplus nouser/nopassword as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 17:37:42 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to an idle instance. SQL> show user USER is "SYS" SQL>
正如上面的演示,我们轻松以SYS身份登录进了数据库,无须给任何用户名密码,甚至是随便给一个毫不存在的用户和密码也可以。
如何防止这样的问题?
首先,我们可以利用oracle自身提供的sqlnet.ora文件中的参数sqlnet.authentication_services。在$ORACLE_HOME/network/admin/sqlnet.ora文件中添加如下行:
sqlnet.authentication_services=(NONE)
再次尝试不提供用户密码登录sqlplus,将遇到ORA-01031错误。
kamus@desktop:~$ sqlplus / as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:05:07 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. ERROR: ORA-01031: insufficient privileges Enter user-name: ^C kamus@desktop:~$ sqlplus sys/oracle as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:06:31 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to an idle instance. SQL>
更进一步,我们还可以让dba组的其他用户必须通过监听程序来连接数据库,这样内置于监听中的审计和跟踪功能就能得到更好的使用。
先来看一下如果不通过监听连接数据库的情况。继续上面的例子,在我们通过用户名密码成功登录数据库实例以后,查看一下操作系统级别的进程。
kamus@desktop:~$ ps -ef|grep sqlplus kamus 6556 5409 0 18:06 pts/0 00:00:00 sqlplus as sysdba kamus 6561 5601 0 18:11 pts/2 00:00:00 grep sqlplus kamus@desktop:~$ ps -ef|grep 6556 | grep -v grep kamus 6556 5409 0 18:06 pts/0 00:00:00 sqlplus as sysdba oracle 6557 6556 0 18:06 ? 00:00:00 oracleorcl11g (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
pid为6556的进程是user process,对应其的server process的pid是6557,这就是oracle使用的双层架构(Two-Task Architecture),任何用户进程(user process)不会跟数据库内存或者数据文件直接交互,而是通过一个对应的服务端进程(server process)来完成工作的。
我们可以注意到,6556进程的属主是kamus,因为是这个用户执行的sqlplus命令,但是6557进程的属主却是oracle,这是为什么呢?这归功于setuid。查看一下oracle可执行文件的权限。
kamus@desktop:~$ cd $ORACLE_HOME/bin kamus@desktop:/u01/app/oracle/product/11.1.0/bin$ ls -l oracle -rwsr-s--x 1 oracle oinstall 144792107 2009-01-05 14:01 oracle
owner的权限是rws,最后的s位表明在该执行文件上启用了setuid,具体含义就是不管是那个用户执行了该文件,该文件总是以属主的身份运行。那么如果我们取消掉s位,会出现什么情况呢?
kamus@desktop:/u01/app/oracle/product/11.1.0/network/admin$ cd kamus@desktop:~$ su - oracle Password: [orcl11g]@desktop[/home/oracle]$cd $ORACLE_HOME/bin [orcl11g]@desktop[/u01/app/oracle/product/11.1.0/bin]$chmod u-s oracle [orcl11g]@desktop[/u01/app/oracle/product/11.1.0/bin]$ls -l oracle -rwxr-s--x 1 oracle oinstall 144792107 2009-01-05 14:01 oracle
再次尝试在kamus用户下登录sqlplus。碰到了ORA-09925错误。
kamus@desktop:~$ sqlplus sys/oracle as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:26:16 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. ERROR: ORA-09925: Unable to create audit trail file Enter user-name:
再检查一下后台进程。
kamus@desktop:~$ ps -ef|grep sqlplus|grep -v grep kamus 6699 5601 0 18:26 pts/2 00:00:00 sqlplus as sysdba kamus@desktop:~$ ps -ef|grep 6699|grep -v grep kamus 6699 5601 0 18:26 pts/2 00:00:00 sqlplus as sysdba kamus 6700 6699 0 18:26 ? 00:00:00 oracleorcl11g (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
原因很清楚,当我们去掉了oracle可执行文件的s位以后,server process的属主成为了kamus,而不是之前的oracle。登录sqlplus需要记录一定的audit信息,这是由server process来完成的,但是因为现在属主是kamus,并没有权限在oracle软件的安装目录中写入任何信息,因此报ORA-09925错误。
更彻底一些,我们连server process都不允许在本地启动,去掉oracle可执行文件的其他用户执行权限,只保留属主的读写执行权限。
[orcl11g]@desktop[/u01/app/oracle/product/11.1.0/bin]$chmod 0700 oracle [orcl11g]@desktop[/u01/app/oracle/product/11.1.0/bin]$ls -l oracle -rwx------ 1 oracle oinstall 144792107 2009-01-05 14:01 oracle
再次尝试登录sqlplus,这次碰到了ORA-12546错误。
kamus@desktop:~$ sqlplus sys/oracle as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:44:14 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. ERROR: ORA-12546: TNS:permission denied Enter user-name:
检查后台进程,可以看到根本就没有启动成功的server process。
kamus@desktop:~$ ps -ef|grep sqlplus|grep -v grep kamus 6916 5601 0 18:44 pts/2 00:00:00 sqlplus as sysdba kamus 6917 6916 0 18:44 ? 00:00:00 [sqlplus] <defunct>
在这种设置下,必须要通过监听才可以登录数据库。
首先,使用oracle用户登陆,启动数据库。取消掉oracle可执行文件的s位后,必须要登陆到该文件的属主用户下,才可以启动数据库。
[orcl11g]@desktop[/home/oracle]$sqlplus sys/oracle as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:56:23 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to an idle instance. SQL> startup ORACLE instance started. Total System Global Area 238530560 bytes Fixed Size 1299116 bytes Variable Size 100666708 bytes Database Buffers 134217728 bytes Redo Buffers 2347008 bytes Database mounted. Database opened. SQL>
然后再登陆kamus用户,尝试登陆sqlplus。orcl11g是在tnsnames.ora文件中已经设置过的连接字串。
[orcl11g]@desktop[/home/kamus]$sqlplus sys/oracle@orcl11g as sysdba SQL*Plus: Release 11.1.0.6.0 - Production on Sun Apr 5 18:57:16 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production With the Partitioning and Real Application Testing options SQL>
通过监听,可以正常连接数据库了。再检查一下后台进程的情况。
[orcl11g]@desktop[/home/kamus]$ps -ef|grep sqlplus|grep -v grep oracle 7077 6966 0 18:56 pts/3 00:00:00 sqlplus as sysdba kamus 7156 7008 0 18:57 pts/5 00:00:00 sqlplus as sysdba [orcl11g]@desktop[/home/kamus]$ps -ef|grep LOCAL|grep -v grep oracle 7118 7077 1 18:56 ? 00:00:02 oracleorcl11g (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) oracle 7172 1 0 18:57 ? 00:00:00 oracleorcl11g (LOCAL=NO)
7077进程是我们使用oracle用户打开的sqlplus连接,对应的server process是7118,7156进程则是使用kamus用户打开的sqlplus连接,可以看到并没有父进程是7156的server process,只有一个7172的进程,它的父进程号是1。
[orcl11g]@desktop[/home/kamus]$ps -fp 1 UID PID PPID C STIME TTY TIME CMD root 1 0 0 17:10 ? 00:00:01 /sbin/init
1是初始化进程,父进程为1代表这个进程是被fork出来的,这就是通过监听连接数据库的机制,user process联系监听,监听再fork一个server process用以应对客户端的请求。
至此,我们已经完成了对于数据库连接的基本安全性设置。
结论:通过下面的两种方法来完成数据库连接的安全保障。
1. 在sqlnet.ora文件中添加sqlnet.authentication_services=(NONE),用以保证必须要给出SYS用户密码才能登陆。
2. 设置oracle可执行文件的运行权限为0700,用以保证非oracle软件的属主必须要通过监听才可以连接数据库。
安全,并不仅仅是局限于数据库本身的,在本文的安全性设置中,它牵涉到数据库运行的机制以及操作系统的部分知识,当你的知识越全面,你就能想到越多的方法来完善整个系统的安全。当然,安全性的建设也远远不局限于技术层面,规章制度、人员素质、完善的审计流程都具有决定性的影响。
User Default Password Check in Oracle 11g
在数据库安全性检查中有一项首先要完成的工作,就是检查数据库中的用户密码是否还仍然保留着默认值,比如sys的密码是否还是change_on_install,system的密码是否还是manager,scott的密码是否还是tiger。
在Oracle 11g之前,我们需要手工来完成这样的工作,大概步骤是:
1. 创建一张自定义的表,保存下常用的系统用户以及默认密码的HASH值。
2. 将系统中的用户密码HASH值与该表中的HASH值比较,如果相同,则表明还在使用默认值。
注意:在数据字典中存储的密码是被HASH算法加密过的,加密后的值不但跟密码本身有关还跟用户名有关,也就是,如果是不相同的用户名那么即使是完全相同的密码,加密后的HASH值也是不一样的。这样保证了每一个用户的每一个密码都有自己独一无二的HASH值。
在Oracle 11g之前,加密后的密码可以从DBA_USERS数据字典的PASSWORD字段中获得,因此可以通过这个字段中存储的值来做是否是默认值的检查。但是在11g中,PASSWORD字段却不再显示密码的内容了。
先看一下文档中对这个字段的描述:
Indicates whether the user is authenticated by OID (GLOBAL) or externally authenticated (EXTERNAL); NULL otherwise
SQL> SELECT username,decode(password,NULL,'NULL',password) password FROM dba_users; USERNAME PASSWORD ------------------------------ ------------------------------ MGMT_VIEW NULL SYS NULL SYSTEM NULL DBSNMP NULL SNPM NULL SYSMAN NULL SNPW NULL SCOTT NULL KAMUS NULL OUTLN NULL WMSYS NULL DIP NULL ORACLE_OCM NULL TSMSYS NULL 14 rows selected
可以看到PASSWORD字段已经不再显示密码内容,全部都为空。
那么,如果再去检查这些用户是否还在使用默认的密码呢?
方法一:从SYS.USER$基表中检查,在基表的password字段中仍然可以查到HASH后的值。
SQL> SELECT name,password FROM user$ WHERE name='SCOTT'; NAME PASSWORD ------------------------------ ------------------------------ SCOTT F894844C34402B67
方法二:这是推荐的方法,最简单的方法,11g中可以使用的方法,11g提供了新的DBA_USERS_WITH_DEFPWD视图,该视图中包含了所有还在使用默认密码的用户名。
SQL> ALTER user scott IDENTIFIED BY tiger; User altered. SQL> SELECT * FROM DBA_USERS_WITH_DEFPWD WHERE username='SCOTT'; USERNAME ------------------------------ SCOTT SQL> ALTER user scott IDENTIFIED BY tiger1; User altered. SQL> SELECT * FROM DBA_USERS_WITH_DEFPWD WHERE username='SCOTT'; no rows selected
Oracle对于安全性的支持力求做到业界领先,Oracle始终在每个细节上进步着。
![Chanel [K]](http://www.dbform.com/wp-content/chanelk.png)