暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

外部系统认证的方式登录到数据库

原创 eygle 2019-09-23
1043

外部认证


如果用户可以直接连接到操作系统,在创建用户时可以指定用户不通过口令,而是通过外部系统认证的方式登录到数据库。


在Windows操作系统中,可以通过修改注册表来实现外部认证。


如果是Oracle 9i版本,需要在HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0(根据你的安装命名有可能不同)下面添加字符串键名OSAUTH_PREFIX_DOMAIN,键值设为FALSE;如果是Oracle 10g版本,需要在HKEY_LOCAL_MACHINE\SOFTWARE\ ORACLE\KEY_OraDb10g_home1(根据你的安装命名有可能不同)下面添加字符串键名OSAUTH_PREFIX_DOMAIN,键值设为FALSE。


然后可以通过如下方式创建用户:


SQL> create user ops$eygle identified externally default tablespace users;
用户已创建。
 
SQL> grant connect to ops$eygle;
授权成功。


这样用户在登录时就不需要显示的输入口令:


SQL> connect /
已连接。
SQL> show user
USER 为 "OPS$EYGLE"


这里的OPS$前缀是为了兼容以前版本保留的:


SQL> show parameter os_authent_prefix
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
os_authent_prefix                    string      OPS$

 

可以将这个前缀设为空值以使用户名更加简单单纯:


SQL> alter system set os_authent_prefix='' scope=spfile;
系统已更改。


在重新启动数据库之后,我们可以创建单纯的外部认证用户:


SQL> create user eygle identified externally default tablespace users;
用户已创建。
SQL> grant connect to eygle;
授权成功。
SQL> select username,password from dba_users where username='EYGLE';
USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          EXTERNAL


此时用新创建的用户连接数据库:


SQL> connect /
已连接。
SQL> show user
USER 为 "EYGLE"


如果不再需要使用操作系统认证,可以通过如下命令将用户修改为使用数据库口令认证:


SQL> alter user eygle identified by eygle;
用户已更改。
SQL> connect /
ERROR:
ORA-01017: invalid username/password; logon denied
 
警告: 您不再连接到 ORACLE。
SQL> connect eygle/eygle
已连接。


值得注意的是REMOTE_OS_AUTHENT应该被设置为FALSE以防止远程系统认证用户的登录:


SQL> alter system set remote_os_authent=false scope=spfile;
系统已更改。


在Linux/UNIX上由于不存在注册表,设置就更为简单:


SQL> alter system set os_authent_prefix='' scope=spfile;
System altered.
SQL> startup force;
ORACLE instance started.
SQL> create user oracle identified externally;
User created.
SQL> grant connect to oracle;
Grant succeeded.
SQL> select username,password from dba_users where username='ORACLE';
USERNAME                       PASSWORD
------------------------------ ------------------------------
ORACLE                         EXTERNAL
SQL> connect /
Connected.
SQL> show user
USER is "ORACLE"


SYS用户行为审计


在很多情况下,可能我们希望审计数据库用户的行为,以便在出现安全问题时能够快速判断,封堵漏洞,保障安全,SYS用户作为一个超级用户,其操作安全尤为重要。


在Oracle 10gR2中,缺省的在audit_file_dest目录会记录SYS用户的登录审计信息,但是并不审计操作内容:


SQL> select * from v$version where rownum <2;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
 
SQL> show parameter audit
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest                      string      /opt/oracle/admin/rac/adump
audit_sys_operations                 boolean     FALSE
audit_syslog_level                   string
audit_trail                          string      NONE
SQL> select a.spid "Process ID",b.sid "Session ID" from v$process a,v$session b
  2  where a.ADDR=b.PADDR
  3  and b.SID= (select sid from v$mystat where rownum = 1);
Process ID   Session ID
------------ ----------
26549               133
 
SQL> ! more /opt/oracle/admin/rac/adump/ora_26549.aud
Audit file /opt/oracle/admin/rac/adump/ora_26549.aud
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Data Mining and Real Application Testing options
ORACLE_HOME = /opt/oracle/product/10.2.0/db10g
System name:    SunOS
Node name:      db210-rac2.eygle.com
Release:        5.9
Version:        Generic_117171-12
Machine:        sun4u
Instance name: rac2
Redo thread mounted by this instance: 2
Oracle process number: 31
Unix process pid: 26549, image: oracle@db210-rac2.eygle.com (TNS V1-V3)
 
Sun Nov 21 17:45:51 2010
LENGTH : '137'
ACTION :[7] 'CONNECT'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'


缺省的审计信息很简略,而audit_sys_operations参数可以帮助实现SYS用户的行为审计,这个参数是静态参数,设置后重启数据库生效:


SQL> alter system set audit_sys_operations=true scope=spfile;
 
System altered.
 
SQL> shutdown immediate;
SQL> startup
SQL> show parameter audit
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest                      string      /opt/oracle/admin/rac/adump
audit_sys_operations                 boolean     TRUE
audit_syslog_level                   string
audit_trail                          string      NONE


现在重新登陆一个SYS会话,看看审计信息会记录哪些内容:


$ sqlplus '/ as sysdba'
SQL*Plus: Release 10.2.0.4.0 - Production on Sun Nov 21 17:53:30 2010
Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
首先查询得到进程号信息:
SQL> select a.spid "Process ID",b.sid "Session ID" from v$process a,v$session b
  2  where a.ADDR=b.PADDR
  3  and b.SID= (select sid from v$mystat where rownum = 1);
Process ID   Session ID
------------ ----------
605                 149
创建测试表,并执行insert/delete等操作
SQL> create table eygle as select * from dba_users;
Table created.
 
SQL> insert into eygle select * from dba_users;
13 rows created.
 
SQL> delete from eygle;
26 rows deleted.
 
SQL> commit;
Commit complete.
查看审计文件
SQL> ! more /opt/oracle/admin/rac/adump/ora_605.aud
Audit file /opt/oracle/admin/rac/adump/ora_605.aud
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Data Mining and Real Application Testing options
ORACLE_HOME = /opt/oracle/product/10.2.0/db10g
System name:    SunOS
Node name:      db210-rac2.eygle.com
Release:        5.9
Version:        Generic_117171-12
Machine:        sun4u
Instance name: rac2
Redo thread mounted by this instance: 2
Oracle process number: 19
Unix process pid: 605, image: oracle@db210-rac2.eygle.com (TNS V1-V3)
注意,SYS用户现在所有的操作都被详细记录下来
Sun Nov 21 17:53:30 2010
LENGTH : '137'
ACTION :[7] 'CONNECT'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'
 
Sun Nov 21 17:53:51 2010
LENGTH : '282'
ACTION :[150] 'select a.spid "Process ID",b.sid "Session ID" from v$process a,v$session b
where a.ADDR=b.PADDR
and b.SID= (select sid from v$mystat where rownum = 1)'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'
 
Sun Nov 21 17:54:03 2010
LENGTH : '176'
ACTION :[45] 'create table eygle as select * from dba_users'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'
 
Sun Nov 21 17:54:13 2010
LENGTH : '172'
ACTION :[41] 'insert into eygle select * from dba_users'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'
 
Sun Nov 21 17:54:16 2010
LENGTH : '148'
ACTION :[17] 'delete from eygle'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'
 
Sun Nov 21 17:54:18 2010
LENGTH : '136'
ACTION :[6] 'commit'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'oracle'
CLIENT TERMINAL:[5] 'pts/1'
STATUS:[1] '0'


用户行为审计与FGA


在Oracle 10g中,审计功能是非常易用和强大的,我们可以通过数据库的审计功能灵活的审计数据库中重要的数据信息访问。


审计功能缺省是关闭的,可以通过设置AUDIT_TRAIL来启用,这个参数是静态参数,修改后需要重新启动数据库。


AUDIT_TRAIL支持几个参数是:


    AUDIT_TRAIL = { none | os | db | db,extended | xml | xml,extended }


None / false - 禁用审计.

db or true - 启用审计功能,审计信息记录在数据库表SYS.AUD$中。

db,extended - 扩展DB审计功能,SQL_BIND 和 SQL_TEXT 同时被记录.

xml- 启用审计,并使用XML格式记录操作系统级审计文件

xml,extended - 扩展XML审计,记录SQL_BIND 和 SQL_TEXT 信息.

os- 启用审计,审计信息直接记录在操作系统审计文件中


注意,如果使用AUD$存放审计信息,可能会导致SYSTEM表空间使用快速增长,一般建议对空间使用进行控制或者对存储表空间进行分离。


SQL> ALTER SYSTEM SET audit_trail=db SCOPE=SPFILE;
System altered.
 
SQL> shutdown immediate;
SQL> startup


创建测试用户:


SQL> create user eygle identified by eygle;
 User created.
 
 SQL> grant connect,resource to eygle;
 Grant succeeded.


设置用户审计,审计SELECT/INSERT/UPDATE/DELETE等操作及其他用户希望审计的内容:


SQL> audit all by eygle by access;
 Audit succeeded.
 
 SQL> audit select table,update table,insert table,delete table by eygle by access;
 Audit succeeded.
 
 SQL> audit execute procedure by eygle by access;
 Audit succeeded.


接下来使用EYGLE用户执行一系列的操作:


SQL> connect eygle/eygle
 Connected.
 SQL> create table eygle as select * from dict;
 Table created.
 
 SQL> insert into eygle select * from dict where rownum <9;
 8 rows created.
 
 SQL> commit;
 Commit complete.
 
 SQL> delete from eygle where rownum <11;
 10 rows deleted.
 
 SQL> commit;
 Commit complete.
 
 SQL> drop table eygle purge;
 Table dropped.


这些操作将被审计记录,查询dba_audit_trail视图可以获得这些审计信息;


SQL> SELECT username,extended_timestamp,owner,obj_name,action_name
  2  FROM   dba_audit_trail WHERE  owner = 'EYGLE' ORDER BY timestamp;
USERNAME   EXTENDED_TIMESTAMP                  OWNER      OBJ_NAME                       ACTION_NAME
---------- ----------------------------------- ---------- ------------------------------ ----------------------------
EYGLE      21-NOV-10 08.13.13.409020 PM +08:00 EYGLE      EYGLE                          CREATE TABLE
EYGLE      21-NOV-10 08.13.13.410456 PM +08:00 EYGLE      from$_subquery$_011            SELECT
EYGLE      21-NOV-10 08.13.13.411143 PM +08:00 EYGLE      from$_subquery$_004            SELECT
EYGLE      21-NOV-10 08.13.26.491018 PM +08:00 EYGLE      EYGLE                          CREATE TABLE
EYGLE      21-NOV-10 08.13.40.987887 PM +08:00 EYGLE      EYGLE                          INSERT
EYGLE      21-NOV-10 08.13.57.095641 PM +08:00 EYGLE      EYGLE                          DELETE
EYGLE      21-NOV-10 08.14.07.876233 PM +08:00 EYGLE      EYGLE                          DROP TABLE


这里值得注意的是,DBA_AUDIT_TRAIL基于底层表AUD$建立,由于AUD$表缺省的建立于SYSTEM表空间,其使用空间可能快速扩展占用大量存储,所以在使用AUDIT特性时,应该考虑将其迁移出SYSTEM表空间,或者定期归档清理审计数据。


在$ORACLE_HOME\rdbms\admin\cataudit.sql中,可以找到创建DBA_AUDIT_TRAIL的详细语句(11g中,AUD$表的创建语法可以在dsec.bsq文件中找到),以下是概要信息:


create or replace view DBA_AUDIT_TRAIL
(OS_USERNAME, USERNAME,USERHOST,TERMINAL,TIMESTAMP,OWNER,OBJ_NAME,ACTION,ACTION_NAME,
NEW_OWNER,NEW_NAME,OBJ_PRIVILEGE,SYS_PRIVILEGE,ADMIN_OPTION,GRANTEE,AUDIT_OPTION,
SES_ACTIONS,LOGOFF_TIME,LOGOFF_LREAD,LOGOFF_PREAD,LOGOFF_LWRITE,LOGOFF_DLOCK,
COMMENT_TEXT,SESSIONID,ENTRYID,STATEMENTID,RETURNCODE,PRIV_USED,CLIENT_ID,ECONTEXT_ID,
SESSION_CPU,EXTENDED_TIMESTAMP,PROXY_SESSIONID,GLOBAL_UID,INSTANCE_NUMBER,OS_PROCESS,
TRANSACTIONID,SCN,SQL_BIND,SQL_TEXT,OBJ_EDITION_NAME,DBID        )
as
select spare1           /* OS_USERNAME */,
       userid           /* USERNAME */,
       userhost         /* USERHOST */,
       terminal         /* TERMINAL */,
       cast (           /* TIMESTAMP */
           (from_tz(ntimestamp#,'00:00') at local) as date),
       obj$creator      /* OWNER */,
       obj$name         /* OBJECT_NAME */,
       aud.action#      /* ACTION */,
       act.name         /* ACTION_NAME */,
       new$owner        /* NEW_OWNER */,
       new$name         /* NEW_NAME */,
       decode(aud.action#,
              108 /* grant  sys_priv */, null,
              109 /* revoke sys_priv */, null,
              114 /* grant  role */, null,
              115 /* revoke role */, null,
              auth$privileges) 
                        /* OBJ_PRIVILEGE */,
       decode(aud.action#,
              108 /* grant  sys_priv */, spm.name,
              109 /* revoke sys_priv */, spm.name,
              null)
                        /* SYS_PRIVILEGE */,
       decode(aud.action#,
              108 /* grant  sys_priv */, substr(auth$privileges,1,1),
              109 /* revoke sys_priv */, substr(auth$privileges,1,1),
              114 /* grant  role */, substr(auth$privileges,1,1),
              115 /* revoke role */, substr(auth$privileges,1,1),
              null)
                        /* ADMIN_OPTION */,
       auth$grantee     /* GRANTEE */,
       decode(aud.action#,
              104 /* audit   */, aom.name,
              105 /* noaudit */, aom.name,
              null)
                        /* AUDIT_OPTION  */,
       ses$actions      /* SES_ACTIONS   */,
       cast((from_tz(cast(logoff$time as timestamp),'00:00') at local) as date)
                        /* LOGOFF_TIME   */,
       logoff$lread     /* LOGOFF_LREAD  */,
       logoff$pread     /* LOGOFF_PREAD  */,
       logoff$lwrite    /* LOGOFF_LWRITE */,
       decode(aud.action#,
              104 /* audit   */, null,
              105 /* noaudit */, null,
              108 /* grant  sys_priv */, null,
              109 /* revoke sys_priv */, null,
              114 /* grant  role */, null,
              115 /* revoke role */, null,
              aud.logoff$dead)
                         /* LOGOFF_DLOCK */,
       comment$text      /* COMMENT_TEXT */,
       sessionid         /* SESSIONID */,
       entryid           /* ENTRYID */,
       statement         /* STATEMENTID */,
       returncode        /* RETURNCODE */,
       spx.name          /* PRIVILEGE */,
       clientid          /* CLIENT_ID */,
       auditid           /* ECONTEXT_ID */,
       sessioncpu        /* SESSION_CPU */,
       from_tz(ntimestamp#,'00:00') at local,
                                   /* EXTENDED_TIMESTAMP */
       proxy$sid                      /* PROXY_SESSIONID */,
       user$guid                           /* GLOBAL_UID */,
       instance#                      /* INSTANCE_NUMBER */,
       process#                            /* OS_PROCESS */,
       xid                              /* TRANSACTIONID */,
       scn                                        /* SCN */,
       to_nchar(substr(sqlbind,1,2000))      /* SQL_BIND */,
       to_nchar(substr(sqltext,1,2000))      /* SQL_TEXT */,
       obj$edition                   /* OBJ_EDITION_NAME */,
       dbid                                      /* DBID */
from sys.aud$ aud, system_privilege_map spm, system_privilege_map spx,
     STMT_AUDIT_OPTION_MAP aom, audit_actions act
where   aud.action#     = act.action    (+)
  and - aud.logoff$dead = spm.privilege (+)
  and   aud.logoff$dead = aom.option#   (+)
  and - aud.priv$used   = spx.privilege (+)
/


以下是一个产品数据库中的案例情况,缺省的AUD$存储于SYSTEM表空间,经过使用扩展该对象已经占用了2.5G的存储空间:


SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
SQL> select segment_name,bytes/1024/1024/1024 GB,tablespace_name from dba_segments
  2  where segment_name='AUD$';
SEGMENT_NAME                 GB TABLESPACE_NAME
-------------------- ---------- ------------------------------
AUD$                        2.5 SYSTEM
SQL> select index_name from dba_indexes where table_name='AUD$';
INDEX_NAME
------------------------------
SYS_IL0000000376C00040$$
SYS_IL0000000376C00041$$


在相关查询中,可以看到AUD$表的全表扫描可能严重影响查询性能:


SQL> select count(*) from dba_audit_trail;
  COUNT(*)
----------
  13485723
Execution Plan
-----------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                         |     1 |    27 | 90257   (2)| 00:18:04 |
|   1 |  SORT AGGREGATE           |                         |     1 |    27 |            |          |
|*  2 |   HASH JOIN RIGHT OUTER   |                         |    13M|   347M| 90257   (2)| 00:18:04 |
|   3 |    INDEX FAST FULL SCAN   | I_STMT_AUDIT_OPTION_MAP |   249 |   996 |     2   (0)| 00:00:01 |
|*  4 |    HASH JOIN RIGHT OUTER  |                         |    13M|   295M| 90135   (2)| 00:18:02 |
|   5 |     INDEX FULL SCAN       | I_SYSTEM_PRIVILEGE_MAP  |   206 |  1030 |     1   (0)| 00:00:01 |
|*  6 |     HASH JOIN RIGHT OUTER |                         |    13M|   231M| 90015   (2)| 00:18:01 |
|   7 |      INDEX FULL SCAN      | I_SYSTEM_PRIVILEGE_MAP  |   206 |  1030 |     1   (0)| 00:00:01 |
|*  8 |      HASH JOIN RIGHT OUTER|                         |    13M|   167M| 89894   (2)| 00:17:59 |
|   9 |       INDEX FULL SCAN     | I_AUDIT_ACTIONS         |   180 |   720 |     1   (0)| 00:00:01 |
|  10 |       TABLE ACCESS FULL   | AUD$                    |    13M|   115M| 89774   (2)| 00:17:58 |
-----------------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
        899  recursive calls
        769  db block gets
     328252  consistent gets
     327603  physical reads
     106624  redo size
          1  rows processed


AUD$对象的内容可以直接Delete或Truncate来清理,其存储空间转移可以通过类似如下步骤进行,如将其移动至SYSAUX表空间(注意编译因此失效的数据库对象):


create table audx tablespace "SYSAUX"  as select * from aud$ where 1 = 2
/
rename AUD$ to AUD$$
/
rename audx to aud$
/


在Oracle 10g之后,Oracle提供了一个内置的功能,可以用于调整审计日志存储位置,通过DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION可以实现迁移。


SQL> truncate table aud$;  --可以根据需要选择是否清理历史数据
Table truncated.
SQL> select count(*) from aud$;
  COUNT(*)
----------
         0
SQL> exec DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(1,'SYSAUX');
PL/SQL procedure successfully completed.
 
SQL> col segment_name for a30
SQL> select segment_name,bytes,tablespace_name from dba_segments where segment_name='AUD$';
SEGMENT_NAME                        BYTES TABLESPACE_NAME
------------------------------ ---------- ------------------------------
AUD$                                65536 SYSAUX


该过程有两个参数;


PROCEDURE SET_AUDIT_TRAIL_LOCATION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 AUDIT_TRAIL_TYPE               BINARY_INTEGER          IN
 AUDIT_TRAIL_LOCATION_VALUE     VARCHAR2                IN


其中AUDIT_TRAIL_TYPE的选项有如下一些:


image.png


可以通过定义常量来设定维护范围,以下语句则是将AUD$和FGA_LOG$一并转移:


SQL> BEGIN
  2  DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(
  3         audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,
  4         audit_trail_location_value =>  'USERS');
  5  END;
  6  /
 
PL/SQL procedure successfully completed.
 
SQL> select segment_name,tablespace_name
2  from dba_segments where segment_name in ('AUD$','FGA_LOG$');
SEGMENT_NAME                                             TABLESPACE_NAME
-------------------------------------------------------- ------------------------------
FGA_LOG$                                                  USERS
AUD$                                                      USERS


在进行对象转移之后,需要检查数据库的失效对象,并且通过运行$ORACLE_HOME\rdbms\admin\utlrp.sql来重新编译失效对象。


这里提到的FGA是指Fine Grained Auditing,通过Oracle FGA特性可以对审计功能进行进一步的扩展,FGA使用FGA_LOG$表记录审计信息。


在测试用户下建立测试表:


SQL> connect eygle/eygle
 Connected.
 SQL> create table eygle as select * from dict where 1=0;
 Table created.


使用SYS用户创建FGA策略:


SQL> connect / as sysdba
 Connected.
 SQL> BEGIN
   2    DBMS_FGA.add_policy(
   3      object_schema   => 'EYGLE',
   4      object_name     => 'EYGLE',
   5      policy_name     => 'AUDIT_EYGLE',
   6      audit_condition => NULL,
   7      audit_column    => 'TABLE_NAME',  --如果设置为NULL,则审计所有COLUMN
   8      statement_types => 'SELECT,INSERT,UPDATE,DELETE');
   9  END;
  10 /
   
 PL/SQL procedure successfully completed.


使用测试用户执行一系列的表操作:


SQL> connect eygle/eygle
 Connected.
 SQL> insert into eygle select * from dict where rownum <3;
 2 rows created.
 SQL> commit;
 Commit complete.
 SQL> delete from eygle where rownum <2;
 1 row deleted.
 SQL> update eygle set table_name='EYGLE' where rownum <2;
 1 row updated.
 SQL> commit;
 Commit complete.
 
 SQL> select * from eygle;
 TABLE_NAME                          COMMENTS
 ------------------------------------- -------------------------------------------
 EYGLE                               Display password limits of the user


使用SYS用户查询审计信息:


SQL> connect / as sysdba
 Connected.
 SQL> select sql_text from dba_fga_audit_trail;
 SQL_TEXT
 --------------------------------------------------------------------------------
 insert into eygle select * from dict where rownum <3
 delete from eygle where rownum <2
 update eygle set table_name='EYGLE' where rownum <2
 select * from eygle


我们可以注意到,所有针对测试表的操作都被记录了下来。


使用SYS用户删除测试策略:

SQL> BEGIN
   2    DBMS_FGA.drop_policy(
   3      object_schema   => 'EYGLE',
   4      object_name     => 'EYGLE',
   5      policy_name     => 'AUDIT_EYGLE');
   6  END;
   7  /
 
 PL/SQL procedure successfully completed.


如果 audit_trail 设置为OS,则审计信息会直接写入操作系统日志,相应的需要设置audit_syslog_level参数。


如下设置两个参数,重启数据库使参数生效:


SQL> ALTER SYSTEM SET AUDIT_TRAIL=OS SCOPE=SPFILE; 
 System altered.
 
 SQL> ALTER SYSTEM SET AUDIT_SYSLOG_LEVEL="local1.warning" SCOPE=SPFILE; 
 System altered.
 
 SQL> shutdown immediate;
 SQL> startup


在操作系统上进行必要的设置(测试用例来自Solaris):


bash-2.05# touch /var/log/audit.log
 bash-2.05# echo "local1.warning  /var/log/audit.log" >> /etc/syslog.conf
 bash-2.05# /etc/init.d/syslog stop   
 bash-2.05# /etc/init.d/syslog start
 syslog service starting.


接下来在另外一个进程创建会话,执行查询:


$ sqlplus eygle/eygle
 SQL*Plus: Release 10.2.0.4.0 - Production on Sun Nov 21 21:17:15 2010
 Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
 
 Connected to:
 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
 With the Partitioning, Real Application Clusters, Data Mining and Real Application Testing options
 
 SQL> select count(*) from dict; 
   COUNT(*)
 ----------
        614


在audit.log日志中将记录详细的审计信息:


Nov 21 21:17:12 db210-rac1 Oracle Audit[6440]: [ID 748625 local1.warning] LENGTH: "156" SESSIONID: "70186" ENTRYID: "1" ACTION: "101" RETURNCODE: "0" LOGOFF$PREAD: "92" LOGOFF$LREAD: "2862" LOGOFF$LWRITE: "8" LOGOFF$DEAD: "0" SESSIONCPU: "41"
Nov 21 21:17:15 db210-rac1 Oracle Audit[6957]: [ID 748625 local1.warning] LENGTH: "262" SESSIONID:[5] "70187" ENTRYID:[1] "1" STATEMENT:[1] "1" USERID:[5] "EYGLE" USERHOST:[24] "db210-rac1" TERMINAL:[5] "pts/2" ACTION:[3] "100" RETURNCODE:[1] "0" COMMENT$TEXT:[26] "Authenticated by: DATABASE" OS$USERID:[6] "oracle" PRIV$USED:[1] "5"
Nov 21 21:17:33 db210-rac1 Oracle Audit[6957]: [ID 748625 local1.warning] LENGTH: "239" SESSIONID:[5] "70187" ENTRYID:[2] "18" STATEMENT:[1] "8" USERID:[5] "EYGLE" USERHOST:[24] "db210-rac1" TERMINAL:[5] "pts/2" ACTION:[1] "3" RETURNCODE:[1] "0" OBJ$CREATOR:[3] "SYS" OBJ$NAME:[4] "OBJ$" OS$USERID:[6] "oracle"


如何切换用户身份


在DBA管理数据库的过程中,经常需要切换为其他用户进行数据库维护,这就需要我们能够进行用户切换。


在Oracle数据库中,可以通过如下方法进行用户身份切换。


(1)通过DBA用户连接数据库,从dba_users视图中查询得到Oracle用户的口令加密串:


SQL> select username,password from dba_users where username='EYGLE';
USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83


注意:在Oracle 11g中,已经不能通过如上查询从DBA_USERS试图获得用户口令。


(2)然后可以修改这个用户的口令并连接到数据库:


SQL> alter user eygle identified by welcome;
用户已更改。
SQL> connect eygle/welcome
已连接。


(3)在另外的session中,用DBA用户迅速将用户口令修改回原来的加密串(防止其他用户登录失败):


SQL> alter user eygle identified by values 'B726E09FE21F8E83';
 
用户已更改。


(4)此时口令被变更回原口令,尽量缩短以上过程可以最小化数据库影响时间:


SQL> connect eygle/eygle
已连接。


而已经作为该用户连接的身份则可以执行一系列的相关操作了。


通过代理用户(Proxy)连接数据库


如果试图通过其他用户身份登录,上面的方法必须要修改用户口令,在那一瞬登录的用户仍然可能获得口令错误的提示,所以在Oracle 10gR2中,Oracle提供了一个更好的解决方案企业用户代理:Enterprise User Proxy。

也就是说,我们可以创建一个公有代理用户,这个用户可以被用于代理企业用户或其他用户向目标用户切换,这个代理权限通常通过类似以下语句进行授权:


ALTER USER target_user GRANT CONNECT THROUGH proxy_user;


来看一下以下的测试例子:


SQL> connect / as sysdba
已连接。
SQL> create user proxy identified by pproxy;
用户已创建。
SQL> grant connect to proxy;
授权成功。
SQL> alter user eygle grant connect through proxy;
用户已更改。
 
SQL> connect proxy[eygle]/pproxy
已连接。
SQL> show user
USER 为 "EYGLE"
SQL> create table eygle (name varchar2(20));
 
表已创建。
 
SQL> select * from session_privs;
PRIVILEGE
----------------------------------------
CREATE SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE CLUSTER
CREATE SEQUENCE
CREATE PROCEDURE
CREATE TRIGGER
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE
 
已选择10行。
 
SQL> connect proxy/pproxy
已连接。
SQL> select * from session_privs;
PRIVILEGE
----------------------------------------
CREATE SESSION


如果读者熟悉UNIX/Linux的话,可能会经常使用sudo(在不同平台中可能需要独立的软件包安装)的方式进行用户身份的切换,类似如下的方式:


[gqgai@eygle gqgai]$ sudo su -
Password:
[root@eygle root]#


如果用户被授权使用sudo,那么就可以通过如上方式利用sudo和su命令,输入用户自己的口令(不是root用户的口令)切换为root身份。这样就可以将root的口令变更和用户权限分离开来,具有sudo权限的用户无需再知道root的口令,root口令的变更也就无需通知其他用户。


sudo工具的含义为以其他用户的身份执行某个命令:


NAME
       sudo - execute a command as another user
 
SYNOPSIS
       sudo -V | -h | -l | -L | -v | -k | -K | -s | [ -H ] [-P ] [-S ] [ -b ]
       | [ -p prompt ] [ -c class|- ] [ -a auth_type ] [ -u username|#uid ]
       command
 
DESCRIPTION
       sudo allows a permitted user to execute a command as the superuser or
       another user, as specified in the sudoers file.


利用Oracle的这个功能,可以在SQL*Plus中实现类似操作系统中的sudo功能,为此可以创建一个sudo的公用帐号:


SQL> connect / as sysdba
已连接。
SQL> create user sudo identified by proxy;
用户已创建。
SQL> alter user eygle grant connect through sudo;
用户已更改。
SQL> connect sudo[eygle]/proxy
已连接。
SQL> select * from tab;
TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
EYGLE                          TABLE
SQL> select * from eygle;
未选定行
SQL> insert into eygle values('eygle');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from eygle;
NAME
--------------------
eygle


这种方式为数据库管理和安全提供了极大的便利。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论