zoukankan      html  css  js  c++  java
  • Oracle 12c用户和安全管理

    前言:

    Oracle 12c的多租户(multitenant)环境与SQL Server的架构非常相似,CDB$ROOT类似于master、PDB$SEED类似于model、各个pluggable database就相当于普通的业务库。
    官方宣传了12c的很多好处但其实没卵用,12c设想通过合并多个库来避免DBLINK的性能问题,但其实还是通过压榨单一服务器来实现的,其他好处诸如PDB迁移方便、JSON支持、资源组、索引压缩、in-memory支持等等要么是炒冷饭,要么实际适用场景很少,不过这些新特性都还有待继续研究,一步一步来。
    首先必须要解决的是登录问题,12c的多租户环境下用户与以前不同了,以前的用户性质都是一样的,而在12c中一个实例下可以有多个可插拔的数据库,因此用户管理与之前就有很大区别了,本文介绍12c用户及其管理,以12.2.0.1版本为例,所有观点来源于如下官网链接:
    本文主要包含以下六个部分:
    • 关于用户安全的简易说明
    • 创建用户
    • 更改用户
    • 配置用户资源限额
    • 删除用户
    • 用户和profile的的数据字典
    一、关于用户安全的简易说明:

    每个数据库都有自己的用户列表,在创建用户时你可以为这个用户设置一系列的登录limits或resource limits,或者使用profile实现此功能,profile就是一个用户所拥有的属性的集合,你可以查看dba_profiles来详细了解。
    此外你还可以为用户赋予一系列的权限和角色,参考:Configuring Privilege and Role Authorization
     
    二、创建用户

    这部分涉及的内容很多,保险起见还是全部列出来的比较好。
    • 关于Common User和Local User
    在多租户的环境中,common user可以访问整个CDB而local user只能访问特定的PDB,关于CDB与PDB的关系这里用官网的一幅图来表示:

    可以看到CDB其实就是指实例下的所有数据库,包含ROOT、Seed和其他所有PDBs,整个Instance可以看做一个容器,即Container DB(CDB).

    你可以使用sysdba用户来启动PDB,有以下两种方式:
    1.alter session set container=orclpdb1;
      alter database open;
      --对应关闭方式为shutdown immediate;
    2.alter pluggable database orclpdb1 open;
      --对应关闭方式为alter pluggable database orclpdb1 close;
    Ps:PDB的关闭是指将PDB由open变为mount状态,彻底shutdown需要到root中关闭整个实例。

    关于Common user:

    Common user必须以C##或者c##开头,你可以通过修改common_user_prefix参数来更改这个prefix,而Local user则必须避免以这个prefix开头。
    Common user的身份和密码对于每个PDB来说都是可见的,只要有合适的权限common user也可以操作PDB。
    Common user通常用于在root中操作PDBs,例如插拔PDB数据库、更改PDB状态或者为CDB指定临时表空间等。
    Common user只能在cdb$root中创建,cdb$root中也只能创建common user。
    举例来讲,common user可做的操作有:创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。当然一个local user如果有权限也可以更改其自身PDB的状态。
    Oracle的系统用户如sys、system等,就是common user,即可操作ROOT数据库也可以操作任意PDB,除非某个PDB开启Vault-enabled来限制系统用户的权限。

    当你将一个non-CDB的数据库作为PDB插入到CDB中时:

    1. non-CDB的系统用户将会与CDB common user合并,即non-CDB中的系统用户将会新增到CDB中,如果username冲突则不新增,这些冲突系统用户的密码全部按照CDB的来,原密码失效。
    2. 如果你曾经更改过原non-CDB系统用户的权限,那么合并之后这些差异权限只对这个PDB生效,对其他PDB无效。这里还不知道如果少了权限合并之后是不是依然少,有需要的时候再测试下好了。
    当你将一个PDB插入CDB时:
    1. 原PDB的common user会失去它所有的公共权限,包括set container的权限。
    2. 如果目标CDB有与PDB同名的common user,那么这两个common user合并,CDB的common user密码优先生效。而PDB中其他不同名的common user将会被锁定。你可以对这些锁定的common user做如下任意一种处理:
      • 不处理这些locked用户,在权限适当的情况下你依然可以使用这些schema下的对象。
      • 使用EXPDP导出这些用户下的数据并导入到另一个用户下,然后删掉此locked user。
      • 关掉PDB,连接到CDB$ROOT,创建同名的common user,然后重开PDB,Oracle会自动处理权限差异,此时你可以unlock这些用户,他们的本地权限保持不变。
    关于Local user:
    Local user就是只存在于PDB中的用户,local user可以拥有管理类权限,但是这类权限只对local user所在的PDB有效。
    Local user与common user的区别可以概括为以下几点:
    1. Local user不能创建common user,也不能在cdb$root中被授予权限。而common user只要有合适的权限,就能创建、修改common/local user,就能公共的或本地的grant/revoke权限。Local user如果权限充足,可以创建、修改local user,也可以在PDB中向common/local user赋权限。
    2. 你可以向local user赋予公共角色或权限(类似于select any table这种),但是这些公共角色或权限包含的权限只对其所属PDB有效。
    3. Local user在一个PDB中应当是唯一的。
    4. 如果local user有合适的权限,那么它也可以访问common user里的对象。
    5. Local user只能在PDB中被创建,PDB中也只能创建local user而不能创建common user。
    6. 你可以根据版本来选择是否禁用local user,但是却不能这么操作common user。
    • 创建用户示例
    创建common user:
    $ sqlplus / as sysdba
    SQL> show pdbs;
        CON_ID CON_NAME			  OPEN MODE  RESTRICTED
    ---------- ------------------------------ ---------- ----------
    	 2 PDB$SEED			  READ ONLY  NO
    	 3 ORCLPDB1			  READ WRITE NO
    	 4 ORCLPDB2			  MOUNTED
    SQL> show con_name
    CON_NAME
    ------------------------------
    CDB$ROOT
    SQL> alter pluggable database orclpdb1 open;
    Pluggable database altered.
    SQL> create user c##test identified by test container=all;  
    --common user只能以c##开头,且强制container=all,创建时可以不用写container=all。
    SQL> grant dba to c##test;
    --至此common user c##test创建完毕,但是目前为止这个common user只能操作CDB$ROOT schema对象下的objects和创建PDB的local user,并没有操作PDB下objects的权限,一般来说common user不必有此权限,但是如果你想拥有,那么:
    SQL> alter session set container=orclpdb1;  --切换至orclpdb1的PDB后再次grant权限
    SQL> grant dba to c##test;
    --至此common user c##test就拥有了操作PDB orclpdb1下objects的权限了。但是这种common user删除时必须添加cascade:
    SQL> drop user c##test;
    drop user c##test
    *
    ERROR at line 1:
    ORA-65048: error encountered when processing the current DDL statement in pluggable database ORCLPDB1
    ORA-01922: CASCADE must be specified to drop 'C##TEST'
    SQL> drop user c##test cascade;
    User dropped.

    创建local user:

    $ sqlplus / as sysdba
    SQL> alter session set container=orclpdb1;
    SQL> create user test identified by test default tablespace users quota 100M on example quota 200M on test temporary tablespace temp profile default container=current;
    --local user只能以非c##开头,且强制container=current,创建时可以不用写container=current。
    SQL> grant connect,resource,unlimited tablespace to test;
    $ sqlplus test/test@localhost/orclpdb1
    --至此local user创建完毕。
    --需要特别注意的一点是:12c的resource角色中已经不包含unlimited tablespace权限因此需要单独赋予,或者通过quota项来分配一定的表空间限额。
    • 创建用户总结:
    一般来说没有必要创建除系统用以外的common user,或者只需要创建一个不含操作具体PDB权限的common user,common user不应当用于操作具体业务数据,正如官方说明的那样,common user通常的操作应当是:
      创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。
    我们可以使用如下SQL来查看PDB或CDB$ROOT库内的用户:
    $ sqlplus / as sysdba
    SQL> alter session set container=orclpdb1;
    SQL> set lines 200
    SQL> set pages 100
    SQL> col username for a40
    SQL> select USERNAME,ACCOUNT_STATUS,COMMON from dba_users;
    --结果可以看到common user是在所有PDB中可见的,在单个PDB中查询dba_users你能看到所有common user和属于本PDB的local user。

    再来考虑一种特殊情况,假如我们需要在一个PDB中访问另一个PDB中的数据呢?
    使用local user是不可能的,因为local user完全PDB隔离,就算local user被赋予了类似dba、select any table这些公共权限,也只是在PDB内有效,无法跨库访问,那么只能使用common user。

    接下来举例common user跨PDBs访问:

    SQL> show pdbs;
        CON_ID CON_NAME			  OPEN MODE  RESTRICTED
    ---------- ------------------------------ ---------- ----------
    	 2 PDB$SEED			  READ ONLY  NO
    	 3 ORCLPDB1			  READ WRITE NO
    	 4 ORCLPDB2			  READ WRITE NO
    --我们有两个PDB:orclpdb1和orclpdb2都是open状态,各自有一个scott用户,用户下分别有一个test1、test2表。我们先创建一个common user:
    $ sqlplus / as sysdba
    SQL> create user c##scott identified by tiger;
    SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
    --然后在orclpdb1中给c##scott赋权限
    SQL> alter session set container=orclpdb1;
    SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
    --接下来在orclpdb2中给c##scott赋权限
    SQL> alter session set container=orclpdb2;
    SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;

    至此c##scott用户就有了在两个pdb中查询的权限,但是此权限是严格PDB隔离的,不能跨库查询。虽然不能像SQL Server那样跨库直接查询,不过oracle却提供了变通的办法--CONTAINERS子句,参考网址如下(此特性开始于12.1.0.2版本):

    举例:SELECT ename FROM CONTAINERS(scott.emp) WHERE CON_ID IN (45, 49);

    想要使用CONTAINERS子句必须满足以下条件:

    1.CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在。
    2.CONTAINERS子句中涉及的表、视图的属主必须是执行SQL语句的common user;如果是同义词,那么这个同义词必须是引用的此common user下的表或视图。
    3.包含CONTAINERS子句的SQL必须在CDB$ROOT数据库下使用common user执行。

    如果CONTAINERS子句涉及的表里有以下列类型,那么会被自动过滤掉:

    1.用户定义的类型:object types, varrays, REFs, and nested tables
    2.系统类型:ANYTYPE, ANYDATASET, URI types, SDO_TOPO_GEOMETRY, SDO_GEORASTER, and Expression
    看完以上5条要求后突然发现这些要求很奇葩,如果CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在,那我还为什么还要跨PDB查询,直接在ROOT中查不就得了?

    稍微思考和实践了一下,发现使用CONTAINERS子句的条件应该是:

    • 必须使用common user在CDB$ROOT中查询
    • CONTAINERS()方法的输入是表、视图或同义词,这个对象必须在CDB$ROOT中有个名称+结构完全相同的对象,无论是表还是视图还是同义词,表可以没有数据。
    • 必须使用执行此查询的common user到表所在的PDB中创建一个同名view,这需要common user拥有查询此表的权限。

    那么接着上边的实例就可以很容易的进行跨PDB查询了:

    1.首先我们使用common user c##scott在orclpdb1中创建针对scott.test1的视图:
    $ sqlplus c##scott/tiger@orclpdb1
    SQL> create view test1 as select * from scott.test1;
    2.然后使用common user c##scott在CDB$ROOT中创建同名的表或者视图:
    $ sqlplus c##scott/tiger
    SQL> create table test1(name varchar2(20));
    3.此时我们就可以使用SQL查询了:
    SQL> select * from CONTAINERS(test1) where con_id=3;
    4.如果还需要联结查询orclpdb2中的test2表,那么:
    $ sqlplus c##scott/tiger@orclpdb2
    SQL> create view test2 as select * from scott.test2;
    $ sqlplus c##scott/tiger
    SQL> create table test2(name varchar2(20));
    5.这样就相当于test1和test2在CDB$ROOT中都有了一个接口,我们通过接口访问相应PDB中的common user下的视图,视图又是直接定义在最终表上的。
     
    画一幅图来直观的表示:
    三、修改用户

    修改用户与创建用户的语法很相似:
    --一个官方示例:
    ALTER USER c##hr_admin
     DEFAULT TABLESPACE data_ts
     TEMPORARY TABLESPACE temp_ts
     QUOTA 100M ON data_ts
     QUOTA 0 ON test_ts
     SET CONTAINER_DATA = (emp_db, hr_db) FOR V$SESSION 
     CONTAINER = CURRENT;
     --有以下几个地方需要解释:
     1.QUOTA的大小表示在表空间上限额的总大小,而非增/减量。
     2.SET CONTAINER_DATA表示此common user在root中访问v$session时可以获取到emp_db和hr_db相关的session信息。

    此外一般用户的密码可以通过alter user语句修改,而sys密码可以通过orapwd工具修改:

    orapwd file='orapworcl' force=y
    orapwd input_file='orapworcl' file='orapwd' sys=y force=y
     
    四、配置用户资源限额

    这点可以通过一个视图很容易的看到:

    因此修改用户资源限额就很简单了,例如:
    alter user scott limit password_life_time unlimited;
    --或者新建一个profile,然后将其指定为用户的profile:
    CREATE PROFILE profile_scott LIMIT
      FAILED_LOGIN_ATTEMPTS 6
      PASSWORD_LIFE_TIME 60
      PASSWORD_REUSE_TIME 60
      PASSWORD_REUSE_MAX 5
      PASSWORD_LOCK_TIME 1/24
      PASSWORD_GRACE_TIME 10
      PASSWORD_VERIFY_FUNCTION DEFAULT;
    alter user scott profile profile_scott; 

    五、删除用户


    六、用户和profile涉及的数据字典

    ALL_OBJECTS
    Describes all objects accessible to the current user
    ALL_USERS
    Lists users visible to the current user, but does not describe them
    DBA_PROFILES
    Displays all profiles and their limits
    DBA_TS_QUOTAS
    Describes tablespace quotas for users
    DBA_OBJECTS
    Describes all objects in the database
    DBA_USERS
    Describes all users of the database
    DBA_USERS_WITH_DEFPWD
    Lists all user accounts that have default passwords
    PROXY_USERS
    Describes users who can assume the identity of other users
    RESOURCE_COST
    Lists the cost for each resource in terms of CPUs for each session, reads for each session, connection times, and SGA
    USER_PASSWORD_LIMITS
    Describes the password profile parameters that are assigned to the user
    USER_RESOURCE_LIMITS
    Displays the resource limits for the current user
    USER_TS_QUOTAS
    Describes tablespace quotas for users
    USER_OBJECTS
    Describes all objects owned by the current user
    USER_USERS
    Describes only the current user
    V$SESSION
    Lists session information for the current database session
    V$SESSTAT
    Displays user session statistics
    V$STATNAME
    Displays decoded statistic names for the statistics shown in the V$SESSTAT view
  • 相关阅读:
    MFC常用数据类型
    第四章 菜单、工具栏和状态栏(第8课)
    Bugku-CTF之文件包含2 (150)
    Bugku-CTF之本地包含( 60)
    Bugku-CTF之前女友(SKCTF)
    《Web安全攻防 渗透测试实战指南》 学习笔记 (四)
    Nmap工具用法详解
    《Web安全攻防 渗透测试实战指南 》 学习笔记 (三)
    《Web安全攻防 渗透测试实战指南》 学习笔记 (二)
    Bugku-CTF之PHP_encrypt_1(ISCCCTF) [fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=]
  • 原文地址:https://www.cnblogs.com/leohahah/p/9662655.html
Copyright © 2011-2022 走看看