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

万里数据库GreatDB数据库安全文档强制访问控制

原创 Dbb 2024-06-20
94

security_mac

规则介绍

在访问数据时,需要验证主体(用户)是否有权访问,而且非法用户即使拿到了数据,也无法读取数据的内容,数据(客体)还要验证拿到数据的用户是否能够读写。实现方法: 给主体一个标记,给客体一个标记,只有主客体相匹配才能执行操作。主体指数据库操作人员,客体指数据。

强制访问控制是安全产品必须实现的一个基本安全属性。Greatdb security 版本的强制访问控制实现是基于BLP模型的“下读,上写”(低安全级的信息向高安全级流动),同时参考了oralce的强制访问控制。下面将从安全标记、策略应用、规则比较、特权管理这四个方面描述强制访问控制的实现。

安全标记(LABEL)

安全标记组件

label是一组预定义的标记组件,包括等级、范围和组这三种组件,三种组件分别从不同的维度对数据进行了描述。一个label最多只能 包含这三种组件,其中必须包含等级,范围和组可以缺省。

  • 等级(LEVEL)

    等级是线性有序的名称序列,用 L=(l1,l2,...,lp)表示。其中 li(1≤i≤p)表示第 i 个名称,任意两个名称 li、lj 之间,若 i≤j,则 li≤lj,于是有 l1≤l2≤...≤lp,其中 l1,l2,...,lp 称为等级分类(以下简称等级)。 用户在定义策略中的等级时,需要为 其指定编号,其编号在 0-9999 之间(编号小的意味着级别较低)。

  • 范围(Compartment)

    范围是集合类型,设集合 C={c1,c2,...,cm}中每一元素都是一名称,c1,c2,..., cm 间彼此独立,无序,则集合 C 及其任意子集称为非等级类别集合,其中 c1,c2,..., cm 称为非等级类别(以下简称为范围)。

  • 组(Group)

    组为树形结构,有父子之分,可以用来描述组织结构。 设树 G={g1,g2,...,gm},其中每一元素都是一名称,g1,g2,...,gm 间有父子之 分,则 g1,g2,...,gm 称为组。一个组最多拥有一个父组。

安全标记语法

Level:[Compartment{,Compartment}]:[Group{,Group}] 在元数据中保存时Level使用num表示,其余用对应的id表示,Level必须必须存在,Compartment和Group没有必须要求。

安全策略

为了更好的管理和应用LABEL,每个等级,范围,组,LABEL都有自己的所属的策略组(policy)。

安全标记的工作原理

标记又被分为用户标记和客体标记,当用户访问客体时,将用户标记和客体标记进行比较,就能轻松的限制用户对敏感信息的访问。

怎么理解安全标记

我们先重新通过举例介绍level, compartment, group,policy。将policy看成一个公司;level为公司内员工的等级比如(P1, P2,P3,P4);compatment为公司内部的部门(行政部,开发部,测试部);group为公司的特殊组(预研组(1,2),专家组(1,2),管理组)这样公司成员可以从三个维度去给划分开。

如一个普通员工的工资数据的标记为P1:行政部:管理组,那么这个可以查看这个数据的只能是含有在等级上大于等于P1,属于财政部,且属于管理组的可以查看,当然用户的label不是这么简单。详见读写规则

但其中Level才是最重要的,compartment 和 group都是在这之上再做一个细分。那compartment 和 group的差别又是什么呢?group是树形结构,compartment是集合,树形关系本身存在包含关系,父包含子,集合是严格区分开,没有一点交集。

策略

  • 创建策略
    • 函数定义
      • MAC_CREATE_POLICY(
            POLICY_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME 策略名称
        
        复制
    • 使用说明
      • 1.POLICY_NAME 不能为空,且必须唯一
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_CREATE_POLICY('P01');
        
        复制
  • 修改策略
    • 函数定义
      • MAC_ALTER_POLICY(
            POLICY_NAME VARCHAR(128),
            NEW_NAME    VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME 要更改的策略名称
        NEW_NAME 更改后的策略名称
        
        复制
    • 使用说明
      • 1.POLICY_NAME 必须存在
        2.NEW_NAME 不能为空,且必须唯一
        
        复制
    • 调用例子
      •  CALL sys_mac.MAC_ALTER_POLICY('P01', 'P02');
        
        复制
  • 删除策略
    • 函数定义
      •  MAC_DROP_POLICY(
            POLICY_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • 1.POLICY_NAME 必须存在
        
        复制
    • 使用说明
      • 1.没有label使用才可以删除。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_DROP_POLICY('P01');
        
        复制
  • 开启策略
    • 函数定义
      •  MAC_ENABLE_POLICY(
          V_POLICY_NAME   VARCHAR(128)
          );
        
        复制
    • 参数说明
      • V_POLICY_NAME    策略名称
        
        复制
    • 使用说明
      • 1.创建策略后默认是开启,即应用到数据后,数据就受该策略保护。
        
        复制
    • 调用例子
      •   CALL sys_mac.MAC_ENABLE_POLICY('P01');
        
        复制
  • 关闭策略
    • 函数定义
      •  MAC_DISABLE_POLICY(
          V_POLICY_NAME   VARCHAR(128)
          );
        
        复制
    • 参数说明
      • V_POLICY_NAME    策略名称
        
        复制
    • 使用说明
      • 1.关闭策略后,该策略就失效,及其对应的读写规则就没有发生作用,如正常数据操作流程。
        
        复制
    • 调用例子
      •  CALL sys_mac.MAC_DISABLE_POLICY('P01');
        
        复制

等级

  • 添加等级
    • 函数定义
      • MAC_CREATE_LEVEL(
            POLICY_NAME VARCHAR(128),
            LEVEL_NAME  VARCHAR(128),
            LEVEL_NUM   INT
          );
        
        复制
    • 参数说明
      • POLICY_NAME    要创建等级的策略名称
        LEVEL_NAME     创建的等级名称
        LEVEL_NUM      创建的等级编号,在 0-9999 之间的整数
        
        复制
    • 使用说明
      • 1.LEVEL_NAME 不能包含“:”和“,”;
        2.指定策略必须存在;
        3.同一个策略中,等级LEVEL_NUM 和等级名称唯一;
        4.每个等级都要有一个等级LEVEL_NUM,LEVEL_NUM越小表示安全等级越低。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_CREATE_LEVEL('P01', 'L01', 1);
        
        复制
  • 修改等级
    • 函数定义
      • MAC_ALTER_LEVEL(
            POLICY_NAME VARCHAR(128),
            LEVEL_NAME  VARCHAR(128),
            NEW_NAME    VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME    要修改等级的策略名称
        LEVEL_NAME     修改的等级名称
        NEW_NAME       修改后的等级名称
        
        复制
    • 使用说明
      • 1.NEW_LEVEL 不能包含“:”和“,”;
        2.待修改等级名必须存在。
        
        复制
    • 调用例子
      • CALL sys_mac.ALTER_LEVEL('P01', 'L01', 'L02');
        
        复制
  • 删除等级
    • 函数定义
      • MAC_DROP_LEVEL(
            POLICY_NAME VARCHAR(128),
            LEVEL_NAME  VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME   待删除等级的策略名
        LEVEL_NAME    待删除等级的名称
        
        复制
    • 使用说明
      • 1.指定等级必须存在;
        2.如果待删除等级被某个标记使用,则拒绝删除。
        
        复制
    • 调用例子
      •  CALL sys_mac.MAC_DROP_LEVEL('P01', 'L01');
        
        复制

范围

  • 添加范围
    • 函数定义
      • MAC_CREATE_COMPARTMENT(
            POLICY_NAME  VARCHAR(128),
            COMPART_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     要添加范围的策略名
        COMPART_NAME    创建的范围名称
        
        复制
    • 使用说明
      • 1.COMPART_NAME 不能包含“:”和“,”;
        2.指定策略必须存在;
        3.同一个策略中,范围名称唯一;
        4.范围独立无序,范围之间是平等关系,没有等级高低之分,范围之间的比较运算采用集合间的包含关系。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_CREATE_COMPARTMENT('P01', 'C01');
        
        复制
  • 修改范围

    • 函数定义

      • MAC_ALTER_COMPARTMENT(
            POLICY_NAME  VARCHAR(128),
            COMPART_NAME VARCHAR(128),
            NEW_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     要修改范围名的策略名
        COMPART_NAME    待修改的范围名称
        NEW_NAME        要修改成的范围名称
        
        复制
    • 使用说明
      • 1. NEW_LEVEL 不能包含“:”和“,”;
        2. 待修改范围名必须存在。
        
        复制
    • 调用例子
      •   CALL sys_mac.MAC_ALTER_COMPARTMENT('P01', 'C01', 'C02');
        
        复制
  • 删除范围
    • 函数定义
      • MAC_DROP_COMPARTMENT(
            POLICY_NAME  VARCHAR(128),
            COMPART_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     待删除范围所在策略名
        COMPART_NAME    待删除的范围名称
        
        复制
    • 使用说明
      • 1. 指定范围必须存在;
        2. 如果待删除范围被某个标记使用,则拒绝删除。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_DROP_COMPARTMENT('P01', 'C01');
        
        复制

分组

  • 添加分组
    • 函数定义
      • MAC_CREATE_GROUP(
            POLICY_NAME VARCHAR(128),
            GROUP_NAME  VARCHAR(128),
            PARENT_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     要添加组的策略名
        GROUP_NUM       创建的组编号,在 0-9999 之间的整数
        GROUP_NAME      创建的组名称
        PARENT_NAME     新创建组的父组的名称
        
        复制
    • 使用说明
      • 1. GROUP_NAME 不能包含“:”和“,”;
        2. 指定策略必须存在;
        3. 同一个策略中,组名称唯一;
        4. 同一个策略中,只能有一个根组,如果 PARENT_NAME 为 NULL,则创建根组;
        5. 组之间的比较运算采用树形结构间的从属关系。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_CREATE_GROUP('P01', 'G01', NULL);
        CALL sys_mac.MAC_CREATE_GROUP('P01', 'G02', 'G01');
        
        复制
  • 修改分组
    • 函数定义
      • MAC_ALTER_GROUP(
            POLICY_NAME  VARCHAR(128),
            GROUP_NAME   VARCHAR(128),
            NEW_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     要修改组名的策略名
        GROUP_NAME      待修改的组名称
        NEW_NAME        要修改成的组名称
        
        复制
    • 使用说明
      • 1. NEW_NAME 不能包含“:”和“,”;
        2. 待修改组名必须存在。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_ALTER_GROUP('P01', 'G01', 'G02');
        
        复制
  • 修改父组
    • 函数定义
      • MAC_ALTER_GROUP_PARENT(
            POLICY_NAME VARCHAR(128),
            GROUP_NAME  VARCHAR(128),
            PARENT_NAME VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME     要更新父组的组所在的策略名
        GROUP_NAME      待更新父组的组名称
        PARENT_NAME     待修改成的父组名称
        
        复制
    • 使用说明
      • 1. 待修改组和待修改成的父组必须存在;
        2. 父组不能是自身,同时不能是自己的子节点;
        3. 组不能构成闭环。
        
        复制
    • 调用例子
      •  CALL sys_mac.MAC_ALTER_GROUP_PARENT('P01', 'G02', 'G01');
        
        复制
  • 删除分组
    • 函数定义
      • MAC_DROP_GROUP(
            POLICY_NAME VARCHAR(128),
            GROUP_NAME  VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME    待删除组所在策略名
        GROUP_NAME     待删除的组名称
        
        复制
    • 使用说明
      • 1. 指定组必须存在;
        2. 待删除的组不能有子节点存在,否则删除失败。
        
        复制
    • 调用例子
      •   CALL sys_mac.MAC_DROP_GROUP('P01', 'G02');
        
        复制

标记

  • 创建标记
    • 函数定义
      • MAC_CREATE_LABEL(
            POLICY_NAME VARCHAR(128),
            LABEL_VALUE VARCHAR(600)
          );
        
        复制
    • 参数说明
      • POLICY_NAME    要创建的标记所在的策略名
        LABEL_VALUE    标记串
        
        复制
    • 使用说明
      • 1. 策略必须存在;
        2. LABEL 中使用的POLICY组件的元素必须已经创建。
        
        复制
    • 调用例子
      •  CALL sys_mac.MAC_CREATE_LABEL('P01', 'L01:C01,C02:G01');
        
        复制
  • 指定ID创建标记
    • 函数定义
      •    MAC_CREATE_LABEL_USE_ID(
             LABEL_ID INT,
             POLICY_NAME VARCHAR(128),
             LABEL_VALUE VARCHAR(600)
           );
        
        复制
    • 参数说明
      • LABEL_ID        标记值,大于0
        POLICY_NAME     要创建的标记所在的策略名
        LABEL_VALUE     标记串
        
        复制
    • 使用说明
      • 1. 策略必须存在;
        2. LABEL 中使用的POLICY组件的元素必须已经创建。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_CREATE_LABEL(1, 'P01', 'L01:C01,C02:G01');
        
        复制
  • 修改标记
    • 函数定义
      • MAC_ALTER_LABEL(
            POLICY_NAME VARCHAR(128),
            LABEL_VALUE VARCHAR(600),
            NEW_VALUE   VARCHAR(600)
          );
        
        复制
    • 参数说明
      • POLICY_NAME      待修改标记所在策略名
        LABEL_VALUE      待修改标记的标记串
        NEW_VALUE        要修改为的标记串
        
        复制
    • 使用说明
      • 1. 指定策略必须存在;
        2. 新的标记串必须是不存在的标记串,如果存在则报错;
        3. 修改标记的用处主要在于可以不用更新表中的标记列,而直接修改标记串,来改变
        原始数据的安全级别;
        4. 如果修改的标记同时应用在用户上,那么用户的标记合法性可能会遭到破坏。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_ALTER_LABEL('P01', 'L01:C01,C02:G01', 'L01::');
        
        复制
  • 删除标记
    • 函数定义
      • MAC_DORP_LABEL(
            POLICY_NAME     VARCHAR(128),
            LABEL_VALUE   VARCHAR(128)
          );
        
        复制
    • 参数说明
      • POLICY_NAME 待删除标记所在策略名
        LABEL_VALUE 待删除标记的标记串
        
        复制
    • 使用说明
      • 1. 指定策略必须存在;
        2. 待删除的标记必须是已存在的标记,否则报错;
        3. 标记可以进行删除,即使标记被应用在表或用户上,这样会导致表或用户的标记失
        效,使用时需注意。
        
        复制
    • 调用例子
      • CALL sys_mac.MAC_DROP_LABEL('P01', 'L01::');
        
        复制
  • 查看标记
    • 将标记转标记id
      • 函数定义
        • mac_char_to_label(string policy_name, string label_value);
          
          复制
      • 参数说明
        • policy_name    待转换标记的策略名
          label_value    待转换的标记值
          
          复制
      • 使用说明
        • 1. 策略必须存在;
          2. 标记值必须存在;
          
          复制
      • 调用例子
        • select mac_char_to_label('P01', 'L01::');
          
          复制
      • 函数
    • 标记id转标记
      • 函数定义
        • mac_label_to_char(int label_id);
          
          复制
      • 参数说明
        • label_id    待转换标记id
          
          复制
      • 使用说明
        • 1. 标记值必须存在。
          
          复制
      • 调用例子
        • select mac_label_to_char(1);
          
          复制

策略应用

用户策略

用户的策略下包括read_label, write_label,default_read_label, default_write_label, row_label 这个5个标记,限制了用户的读写范围。用户可以被应用多个策略,但每个策略对用户只能应用一次。那为什么用户要有这么多个label呢?而不是一个客体一个label用户一个label,当时第一个版本就是这么做的,我们之所以改是因为当时读写满足必须是level相等,其它能改的数据因不能见又被划为不能改,能读的数据改不了,能操作的范围太少。后面才去参考oracle的强制访问控制,将一个label改成5个。从理论上来说,一个label就是满足BLP模型的(下读,上写)数据只能从低安全级的信息向高安全级流动,缺少灵活性,而且可能破坏高安全客体中数据完整性,不太适用大多数的场景。oracle的强制访问可以说是一个对BLP模型的改进。先简单从level的角度对6种level做一个说明:

read_label: 小于等于该level的数据对用户都是可见的。
write_label: 大于等于该level的数据 并且小于等于read_label的数据是可改的。
既然有这两个label可以确定用户的读写范围了,那为什么还需要下面3个label呢? 为了满足用户自己在安全区间内做灵活的调整,筛选数据,用户可以自己设置session的读写范围。下面三个label是安全管理员给用户默认设置的,用户登录后可以根据自己的需求,在合理区间内调整。
default_read_label: 用户登录默认的读范围。
default_write_label: 用户默认的写范围。
row_label:用户插入数据时的默认label值,最终转换为id。
复制
  • read_label
    • 设置用户最大读的level, compartment, gorup,表示为max_level:read_comps:read_groups。
  • wirte_label

    • 设置用户写范围,表示为min_level:write_comps:write_groups。有如下规则限制

    • min_level <= max_level
      write_comps ⊆ read_comps
      write_groups ⊆ read_groups
      
      复制

其中level为用户的min_level限制用户最小写等级。

  • default_read_label

    • 用户登录后默认用于读的label,即session read label。表示为def_read_level:def_read_comps:def_read_groups。 有如下规则

    • min_level <= def_read_level <= max_level 
      def_read_comps ⊆ read_comps
      def_read_groups ⊆ read_groups
      
      复制
  • default_write_label

    • 用户登录后默认用于写的label,即session wirte label,是通过计算得到的。表示为min_level:def_write_comps:def_write_groups。 有如下规则

    • min_level
      def_write_comps = (wirte_comps ∩ def_read_comps)
      def_wirte_groups = (wirte_groups ∩ def_read_groups)
      
      复制
  • row_label

    • 用户登录后的session row label的初始值, 用户insert 时没有指定插入值时的表前列的插入默认值。表示为row_level:row_comps:row_groups。有如下规则

    • min_level <= row_level <= def_level
      row_comps ⊆ (wirte_comps ∩ def_read_comps)
      row_groups ⊆ (wirte_groups ∩ def_read_groups)
      
      复制

上述group都是不扩展的group,没有扩展出子集来比较。原因是group的父组可以调整。

  • 用户规则设置要求

    • level:
        max_level >= min_level
        max_level >= def_level >= min_level
        def_level >= row_level >= min_level
        ==> max_level >= def_level >= row_level >= min_level
      
      compartments:
        write_comps ⊆ read_comps
        def_comps ⊆ read_comps
        row_comps ⊆ (wirte_comps ∩ def_comps)
      
      groups:
        write_groups ⊆ read_groups
        def_groups ⊆ read_groups
        row_groups ⊆ (wirte_groups ∩ def_groups)
      
      复制
  • 应用用户策略

    • 函数定义
      • MAC_APPLY_USER_POLICY(
            V_USER          VARCHAR(32),
            V_HOST          VARCHAR(255),
            POLICY_NAME     VARCHAR(128),
            READ_LABEL      VARCHAR(600),
            WRITE_LABEL     VARCHAR(600),
            DEF_LABEL       VARCHAR(600),
            ROW_LABEL       VARCHAR(600));
        
        复制
    • 参数说明
      • V_USER        用户名
        V_HOST        用户的HOST
        POLICY_NAME   待设置策略名
        READ_LABEL    待设置的用户的读LABLE
        WRITE_LABEL   待设置的用户的写LABLE
        DEF_LABEL     待设置的用户的默认LABLE
        ROW_LABEL     待设置的用户的行LABLE
        
        复制
    • 使用说明
      • 1. 策略必须存在;
        2. 使用的标记不用提前创建,但其中元素必须存在,且符合标记语法;
        3. READ_LABEL 对应用户的read_label;
        4. WRITE_LABEL对应write_label;
        5. DEF_LABEL对应default_read_label;              
        6. ROW_LABEL对应row_label 所以传入的参数必须满足对应label的要求;
        7. 用户的default_write_label会根据WRITE_LABEL,和DEF_LABEL推导出的;
        8. 所有LABEL的设置必须满足用户规则设置要求。
        
        复制
    • 调用例子
      •  call sys_mac.mac_apply_user_policy('root', 'localhost', 'P1', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01');
        
        复制
  • 更改用户策略

    • 函数定义
      • MAC_ALTER_USER_POLICY(
            V_USER          VARCHAR(32),
            V_HOST          VARCHAR(255),
            POLICY_NAME     VARCHAR(128),
            READ_LABEL      VARCHAR(600),
            WRITE_LABEL     VARCHAR(600),
            DEF_LABEL       VARCHAR(600),
            ROW_LABEL       VARCHAR(600));
        
        复制
    • 参数说明
      •     V_USER          用户名
            V_HOST          用户的HOST
            POLICY_NAME     待更改的策略名
            READ_LABEL      更新后的用户的读标记值
            WRITE_LABEL     更新后的用户的写标记值
            DEF_LABEL       更新后的用户的默认LABLE
            ROW_LABEL       更新后的用户的行LABLE
        
        复制
    • 使用说明
      • 1. 指定策略必须存在;
        2. 如果想更改用户的标记,需要调用该接口;
        3. 更改标记必须满足用户规则设置要求。
        
        复制
    • 调用例子
      •   call sys_mac.mac_alter_user_policy('root', 'localhost', 'P1', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01');
        
        复制
  • 删除用户策略

    • 函数定义
      • MAC_DROP_USER_POLICY(
            V_USER          VARCHAR(32),
            V_HOST          VARCHAR(255),
            POLICY_NAME     VARCHAR(128));
        
        复制
    • 参数说明
      • V_USER          用户名
        V_HOST          用户的HOST
        POLICY_NAME     待删除的用户策略
        
        复制
    • 使用说明
      • 1. 指定策略必须存在。
        
        复制
    • 调用例子
      • call sys_mac.mac_drop_user_policy('root', 'localhost', 'P1');
        
        复制
  • session labels

    • 在用户应用策略生效后,重新登录后session中就包含了READ_LABEL,WRITE_LABEL ,DEF_READ_LABEL,DEF_WRITE_LABEL ,DEF_ROW_LABEL。默认是用户元数据中对应的label,但 READ_LABEL,WRITE_LABEL,DEF_READ_LABEL, DEF_WRITE_LABEL 中的group是扩展开了的,为了便于进行规则的比较。可以通过mac_get_seesion_labels查看。

    • 函数定义

      • mac_get_session_labels(string policy_name);
        
        复制
    • 参数说明
      • policy_name   策略名
        
        复制
    • 使用说明
      • 1. 指定策略必须存在
        
        复制
    • 调用例子
      • select mac_get_session_labels('P1');
        
        复制
  • DEF_READ_LABEL的调整

    • 用户登录后,使用用户的default_label赋值,并且可以通过mac_set_def_label 函数设置,但必须满足default_label设定规则,且在当前session结束后就失效,更改session label 后可能会影响DEF_ROW_LABEL和DEF_WRITE_LABEL。在读请求时,以DEF_READ_LABEL为准;写请求可能只有部分组件使用,详见读写规则。再调整完def_write_label和 def_row_label后扩展开group。

      • def_write_label对应的调整
        • 1. level依然为min_level;
          2. compartment为 write_comps ∩ DEF_READ_LABEL.write_comps;
          3. group 等于 write_groups ∩ DEF_READ_LABEL.def_read_groups 使用DEF_READ_LABEL.def_read_groups作为驱动,按元素依次遍历write_label.group.得到交集,并全部扩展;
          
          复制
      • def_row_label对应的调整
        • 1. level = def_read_label.level;
          2. compartment = def_write_label.compartment;
          3. group 等于 write_groups ∩ DEF_READ_LABEL.def_read_groups使用DEF_READ_LABEL.def_read_groups作为驱动,按元素依次遍历write_label.group.得到交集,但不扩展;
          
          复制
      • 函数定义
        • mac_set_def_label(string policy_name, string label_value);
          
          复制
      • 参数说明
        • policy_name    待更改的def_label所属的策略名
          label_value    更新的def_label值
          
          复制
      • 使用说明
        • 1. 当前用户已经应用了该策略;
          2. 更改后的def_label必须满足用户规则设置要求。
          
          复制
      • 调用例子
        • select mac_set_def_label('P1', 'L1:C1:G1');
          
          复制
  • DEF_ROW_LABEL的调整

    • 用户登录后,使用用户row_label赋值,并可以通过mac_set_row_label设置,但必须满足row_label的设定规则,且当前session结束后失效。用户insert 时没有指定插入值时的表前列的插入默认值。

    • 函数定义

      • mac_set_row_label(string policy_name, string label_value);
        
        复制
    • 参数说明
      • policy_name    待更改的row_label所属的策略名
        label_value    更新的row_label值
        
        复制
    • 使用说明
      • 1. 当前用户已经应用了该策略;
        2. 更改后的row_label必须满足用户规则设置要求。
        
        复制
    • 调用例子
      • select mac_set_row_label('P1', 'L1:C1:G1');
        
        复制
  • 重置session labels

  • 调用mac_reset_session_labels,重新从元数据表加载指定策略的用户的session label信息。

    • 函数定义
      • mac_reset_session_labels(string policy_name);
        
        复制
    • 参数说明
      • policy_name    待重置的策略名
        
        复制
    • 使用说明
      • 1. 当前用户已经应用了该策略。
        
        复制
    • 调用例子
      • select mac_reset_session_labels('p1');
        
        复制

行策略

  • 应用行策略

    • 为表添加一列,列名为_gdb_mac_policy${pid}的标记列,类型为INT。并指定初始值LABEL_VALUE,再创建后根据用户的row_label指定。一个行上可以应用多个策略,但一个策略对表只能应用一次。

    • 函数定义

      • sys_mac.MAC_APPLY_ROW_POLICY(
          V_DB_NAME         VARCHAR(64), 
          V_TABLE_NAME      VARCHAR(64),
          V_POLICY_NAME     VARCHAR(128),
          V_LABEL           VARCHAR(600),
          V_OPTION_VISIBLE  INT);
        
        复制
    • 参数说明
      • V_DB_NAME         库名,不能为系统库
        V_TABLE_NAME      表名
        V_POLICY_NAME     策略名
        V_LABEL           已经创建好的label,其id做为已有数据的策略列的默认值
        V_OPTION_VISBLE   是否为隐藏列 0为隐藏,1为非隐藏。
        
        复制
    • 使用说明
      • 1. 指定策略必须存在;
        2. 策略不能应用在系统表、临时表、视图上。
        
        复制
    • 调用例子
      • call sys_mac.MAC_APPLY_ROW_POLICY('test', 't1', 'P1', 1, 1);
        
        复制
  • 删除行策略

  • 删除策略后,删除该标记列。

    • 函数定义
      • sys_mac.MAC_DROP_ROW_POLICY(
          V_DB_NAME         VARCHAR(64), 
          V_TABLE_NAME      VARCHAR(64),
          V_POLICY_NAME     VARCHAR(128));
        
        复制
    • 参数说明
      •   V_DB_NAME         待删除行策略的库名
          V_TABLE_NAME      待删除行策略的表名
          V_POLICY_NAME     待删除行策略名
        
        复制
    • 使用说明
      • 1. 指定的策略必须存在;
        2. 删除策略后drop掉表对应的标记列。
        
        复制
    • 调用例子
      • call sys_mac.MAC_DROP_ROW_POLICY('test', 't1', 'p1');
        
        复制
  • 开启行策略

  • 在对行应用策略后,开关默认是开启的,每次访问数据需要检查是否符合读写权限。

    • 函数定义
      •  sys_mac.MAC_ENABLE_ROW_POLICY(
          V_DB_NAME         VARCHAR(64), 
          V_TABLE_NAME      VARCHAR(64),
          V_POLICY_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • V_DB_NAME         待开启行策略的库名
        V_TABLE_NAME      待开启行策略的表名
        V_POLICY_NAME     待开启行策略名
        
        复制
    • 使用说明
      • 1. 指定的策略必须存在。
        
        复制
    • 调用例子
      • call sys_mac.MAC_ENABLE_ROW_POLICY('test', 't1', 'p1');
        
        复制
  • 关闭行策略

  • 关闭已应用的某个策略后,该策略在该表上不生效。

    • 函数定义
      •  sys_mac.MAC_ENABLE_ROW_POLICY(
          V_DB_NAME         VARCHAR(64), 
          V_TABLE_NAME      VARCHAR(64),
          V_POLICY_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • V_DB_NAME         待关闭行策略的库名
        V_TABLE_NAME      待关闭行策略的表名
        V_POLICY_NAME     待关闭行策略名
        
        复制
    • 使用说明
      • 1. 指定的策略必须存在。
        
        复制
    • 调用例子
      • call sys_mac.MAC_ENABLE_ROW_POLICY('test', 't1', 'p1');
        
        复制
  • 行策略生效后的行为

    • select
      • 根据读规则,确定用户对数据的可见性,只返回对用户可见数据。标记列为隐藏时,使用SELECT *查询 ,隐藏的标记列不显示,如需查询标记列的值,需要指定对应列名。
    • insert
      • 标记列的值如果显示指定,那么必须满足当前用户写的权限,如果没有指定,就为当前用户row_label的id值。当存在隐藏标记列时,Insert没有指定列名时,隐藏标记列没有计算在插入列中。
    • update
      • 更改的数据必须满足用户有写权限,且不能更改标记列的值。如果更新的行可见但不可写,报错。
    • delete
    • 删除的数据必须满足用户有写权限。如果删除的行可见但不可写,报错。

扩展客体策略

库策略
  • 对库应用的策略
    • 函数定义
      • MAC_APPLY_DATABASE_POLICY(
            DB_NAME         VARCHAR(64),
            POLICY_NAME     VARCHAR(128),
            LABEL_VALUE     VARCHAR(600) 
          );
        
        复制
    • 参数说明
      • DB_NAME         库名,不能为系统数据库名
        POLICY_NAME     应用的策略名
        LABEL_VALUE     应用的标记值
        
        复制
    • 使用说明
      • 1. LABEL_VALUE 和 POLICY_NAME必须存在;
        2. DB必须存在,且不能是系统库。
        
        复制
    • 调用例子
      • call sys_mac.MAC_APPLY_DATABASE_POLICY('test', 'P1', 'L1:C1:G1');
        
        复制
  • 更改库应用的策略
    • 函数定义
      • MAC_ALTER_DATABASE_POLICY(
            DB_NAME         VARCHAR(64),
            POLICY_NAME     VARCHAR(128),
            LABEL_VALUE     VARCHAR(600)
          );
        
        复制
    • 参数说明
      • DB_NAME         待修改的数据库名
        POLICY_NAME     待修改的数据库已经应用的策略名
        LABEL_VALUE     更新的标记值
        
        复制
    • 使用说明
      • 1. 在DATABASE下面的策略必须存在;
        2. LABLE_VALUE必须存在,不存在必须提前创建;
        3. 只能更改对应策略的标记值,改变可见范围。
        
        复制
    • 调用例子
      • call sys_mac.MAC_ALTER_DATABASE_POLICY('test', 'P1', 'L2:C2:G2');
        
        复制
  • 删除库应用的策略
    • 函数定义
      •  MAC_DROP_DATABASE_POLICY(
            DB_NAME         VARCHAR(64),
            POLICY_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • DB_NAME         待删除的数据库名
        POLICY_NAME     待删除的数据库已经应用的策略名
        
        复制
    • 使用说明
      • 1. 指定的策略必须存在。
        
        复制
    • 调用例子
      • call sys_mac.MAC_DROP_DATABASE_POLICY('test', 'P1');
        
        复制
表策略
  • 对表应用策略
    • 函数定义
      • MAC_APPLY_TABLE_POLICY(
            DB_NAME         VARCHAR(64),
            TABLE_NAME      VARCHAR(64),
            POLICY_NAME     VARCHAR(128),
            LABEL_VALUE     VARCHAR(600) 
          )
        
        复制
    • 参数说明
      • DB_NAME         库名,不能为系统数据库名
        TABLE_NAME      表名
        POLICY_NAME     应用的策略名
        LABEL_VALUE     应用的标记值
        
        复制
    • 使用说明
      • 1. LABEL_VALUE 和 POLICY_NAME必须存在;
        2. DB必须存在,且不能是系统库。
        
        复制
    • 调用例子
      • call sys_mac.MAC_APPLY_TABLE_POLICY('test', 't1', 'P1', 'L1:C1:G1');
        
        复制
  • 修改对表应用的策略
    • 函数定义
      • MAC_ALTER_TABLE_POLICY(
            DB_NAME         VARCHAR(64),
            TABLE_NAME      VARCHAR(64),
            POLICY_NAME     VARCHAR(128),
            LABEL_VALUE     VARCHAR(600) 
          );
        
        复制
    • 参数说明
      • DB_NAME         待修改的数据库名
        TABLE_NAME      待修改的表名
        POLICY_NAME     待修改的数据库已经应用的策略名
        LABEL_VALUE     更新的标记值
        
        复制
    • 使用说明
      • 1. 在表上的策略必须存在;
        2. LABLE_VALUE必须存在,不存在必须提前创建;
        3. 只能更改对应策略的标记值,改变可见范围。
        
        复制
    • 调用例子
      • call sys_mac.MAC_ALTER_TABLE_POLICY('test', 't1', 'P1', 'L2:C2:G2');
        
        复制
  • 删除对表应用的策略
    • 函数定义
      • MAC_DROP_TABLE_POLICY(
            DB_NAME         VARCHAR(64),
            TABLE_NAME      VARCHAR(64),
            POLICY_NAME     VARCHAR(128)
          );
        
        复制
    • 参数说明
      • DB_NAME         待删除的数据库名
        TABLE_NAME      待删除的表名
        POLICY_NAME     待删除的数据库已经应用的策略名
        
        复制
    • 使用说明
      • 1. 在表上的策略必须存在;
        
        复制
    • 调用例子
      • call sys_mac.MAC_DROP_TABLE_POLICY('test', 't1', 'P1');
        
        复制
列策略
  • 对列应用策略
    • 函数定义
      • MAC_APPLY_COLUMN_POLICY(
            DB_NAME       VARCHAR(64),
            TABLE_NAME    VARCHAR(64),
            COLUMN_NAME   VARCHAR(64),
            POLICY_NAME   VARCHAR(128),
            LABEL_VALUE   VARCHAR(600) 
          );
        
        复制
    • 参数说明
      • DB_NAME         库名,不能为系统数据库名
        TABLE_NAME      表名
        COLUMN_NAME     列名
        POLICY_NAME     应用的策略名
        LABEL_VALUE     应用的标记值
        
        复制
    • 使用说明
      • 1. LABEL_VALUE 和 POLICY_NAME必须存在;
        2. DB必须存在,且不能是系统库。
        
        复制
    • 调用例子
      • call sys_mac.MAC_APPLY_COLUMN_POLICY('test', 't1', 'c1', 'P1', 'L1:C1:G1');
        
        复制
  • 修改对表应用的策略
    • 函数定义
      • MAC_ALTER_COLUMN_POLICY(
            DB_NAME       VARCHAR(64),
            TABLE_NAME    VARCHAR(64),
            COLUMN_NAME   VARCHAR(64),
            POLICY_NAME   VARCHAR(128),
            LABEL_VALUE   VARCHAR(600) 
          );
        
        复制
    • 参数说明
      • DB_NAME         待修改的数据库名
        TABLE_NAME      待修改的表名
        COLUMN_NAME     待修改的列名
        POLICY_NAME     待修改的数据库已经应用的策略名
        LABEL_VALUE     更新的标记值
        
        复制
    • 使用说明
      • 1. 在列上的策略必须存在;
        2. LABLE_VALUE必须存在,不存在必须提前创建;
        3. 只能更改对应策略的标记值,改变可见范围。
        
        复制
    • 调用例子
      • call sys_mac.MAC_ALTER_COLUMN_POLICY('test', 't1', 'c1', 'P1', 'L2:C2:G2');
        
        复制
  • 删除对表应用的策略
    • 函数定义
      • MAC_DROP_COLUMN_POLICY(
            DB_NAME       VARCHAR(64),
            TABLE_NAME    VARCHAR(64),
            COLUMN_NAME   VARCHAR(64),
            POLICY_NAME   VARCHAR(128)
          );
        
        复制
    • 参数说明
      • DB_NAME         待删除的数据库名
        TABLE_NAME      待删除的表名
        COLUMN_NAME     待删除的列名
        POLICY_NAME     待删除的数据库已经应用的策略名
        
        复制
    • 使用说明
      • 1. 在列上的策略必须存在;
        
        复制
    • 调用例子
      • call sys_mac.MAC_DROP_COLUMN_POLICY('test', 't1', 'c1', 'P1');
        
        复制
扩展客体生效后的行为

DML没有读写权限直接报错。在database、table、column之间存在层级关系,如果上一层有权限,下层的都有权限,如果上一层没有权限,下次有权限也不能访问,这个和acl的控制有点区别。

读写规则

读规则

读是使用DEF_READ_LABEL,读规则详见下图,其中的没有特别说明都是指DEF_READ_LABEL中的元素。


写规则

写必须要满足读,使用的是DEF_READ_LABEL,DEF_WRITE_LABEL共同判断。写规则详见下图,其中的没有特别说明都是指DEF_READ_LABEL中的元素。


特权管理

读写特权

如果一个用户在策略上拥有对应的特权,就不需要检查对应的读写权限。

  • 策略读特权(READ)
    • 当一个用户有在某个policy上有读特权时,对受该策略保护的数据可见。
  • 策略写特权(FULL)
    • 当一个用户有在某个policy上有FULL特权时,对受该策略保护的数据可见可写。
  • 设置读写特权
    • 函数定义
      • sys_mac.MAC_SET_USER_PRIV(
          V_USER          VARCHAR(32),
          V_HOST          VARCHAR(255),
          POLICY_NAME     VARCHAR(128),
          V_PRIVS         enum('read', 'full'));
        
        复制
    • 参数说明
      •   V_USER          用户名
          V_HOST          用户host
          POLICY_NAME     设置特权的策略名
          V_PRIVS         特权类型,read 为读特权,full为写特权
        
        复制
    • 使用说明
      • 1. 策略必须存在。
        
        复制
    • 调用例子
      • call sys_mac.MAC_SET_USER_PRIV('root', 'localhost', 'P1', 'read');
        
        复制
  • 清理用户特权

使用MAC_DROP_USER_POLICY清理

特权用户

特权用户具有不受任何policy限制的权限。

  • 添加特权用户
    • 函数定义
      • MAC_GRANT_USER_ALL_PRIVS(
          V_USER          VARCHAR(32),
          V_HOST          VARCHAR(255));
        
        复制
    • 参数说明
      • V_USER    用户名
        V_HOST    用户HOST
        
        复制
    • 调用例子
      • call sys_mac.MAC_GRANT_USER_ALL_PRIVS('root', 'localhost');
        
        复制
  • 删除特权用户
    • 函数定义
      • sys_mac.MAC_REVOKE_USER_ALL_PRIVS(
          V_USER          VARCHAR(32),
          V_HOST          VARCHAR(255));
        
        复制
    • 参数说明
      • V_USER    待清理的用户名
        V_HOST    待清理的用户HOST
        
        复制
    • 调用例子
      • call sys_mac.MAC_REVOKE_USER_ALL_PRIVS('root', 'localhost');
        
        复制

强制访问开关控制

  • 强制访问开关

    • start_with_mandatory_access_control默认为false,为readonly参数。

    • set persist_only start_with_mandatory_access_control = ON;
      restart;
      
      复制
  • 控制session是否使用强制访问开关

    • enable_mandatory_access_control默认为false,为global参数。

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

文章被以下合辑收录

评论