强制访问权限控制 本页介绍天翼云TeleDB数据库中强制访问控制。 强制访问是基于自定义的安全策略最终通过标签实现对用户和表的行级安全加密。安全策略(Policy)是等级(Level)和隔离区(Compartment),组(Group)和标签(Label)的集合,最终通过绑定标签实现行级安全。其实现原理是将表和用户绑定到标签上,再由标签关联等级(必选),隔离区(可选)和安全组(可选),形成了一个多级的行级安全加密体系。 安全策略(Policy):是指创建等级(Level),隔离区(Compartment),组(Group)和标签(Label)必须指定所属的安全策略。 等级(Level):提供第二等级的安全控制,标签必须指定等级。 隔离区(Compartment):提供第二等级的安全控制,可选。 组(Group):提供第三等级的安全控制,一种树状的结构,可选。 标签(Label):最终通过标签绑定体现行级安全。仅当用户被赋予的标签比此行标签有相同或更高等时,该行才可以被用户存取。 注意 分号(:)和逗号(,)保留用于多级安全体系的表达,安全策略中组件的名字不要使用。 在Teledb中,创建安全策略需要通过teledbxmls插件,需要创建插件 SQL CREATE EXTENSION teledbxmls; 安全策略 通过MLSCLSCREATEPOLICY()函数创建安全策略 SQL SELECT MLSCLSCREATEPOLICY(policyname, policyid) 参数描述: policyname(策略名称): 要创建的策略的名称,大小写敏感,不可以空。 policyid(策略ID): 用于标识策略的唯一ID,取值范围[1, 100]。 安全等级(Level) 通过函数MLSCLSCREATELEVEL()函数创建安全等级。 SQL SELECT MLSCLSCREATELEVEL(policyname, levelid, shortname, longname) 参数描述: policyname(策略名称): 指定要添加安全级别的策略名称,不可以为空。 levelid(级别ID): 用于标识安全级别的唯一ID,取值范围[0, 32767]。 shortname(名称): 安全级别的名称,大小写敏感,不可为空,不可以含空格和tabj键。 shortname(名称): 安全级别的名称,大小写敏感,不可为空,不可以含空格和tabj键。 longname(完整名称): 安全级别的描述。 通过MLSCLSALTERLEVELDESCRIPTION()函数修改等级的标签描述。 SQL SELECT MLSCLSALTERLEVELDESCRIPTION(policyname, levelid, longname) 安全隔离区(Compartment) 通过MLSCLSCREATECOMPARTMENT()函数创建安全隔离区(Compartment)。 SQL SELECT MLSCLSCREATECOMPARTMENT(policyname, compartmentid, shortname, longname) 参数 描述 : policyname(策略名称): 指定要添加安全隔离区的策略名称。 compartmentid(隔离区ID): 用于标识安全隔离区的唯一ID,取值范围[0, 32767]。 shortname(简称): 安全隔离区的简称。 longname(完整名称): 安全隔离区的完整名称。 安全组(Group) 通过MLSCLSCREATEGROUPROOT()函数创建新的安全组根节点(Group Root) SQL SELECT MLSCLSCREATEGROUPROOT(policyname, rootid, shortname, longname) 参数描述: policyname(策略名称): 指定要创建安全组根节点的策略名称。 rootid(根节点ID): 用于标识安全组根节点的唯一ID。 shortname(简称): 安全组根节点的简称。 longname(完整名称): 安全组根节点的完整名称。 通过MLSCLSCREATEGROUPNODE()函数在数据库中创建新的安全组子节点(Group Node)并将其设置为指定父节点的子节点。 SQL SELECT MLSCLSCREATEGROUPNODE(policyname, childid, shortname, longname, parentshortz) 参数描述: policyname(策略名称): 指定要创建安全组子节点的策略名称。 childid(子节点ID): 用于标识安全组子节点的唯一ID。 shortname(简称): 安全组子节点的简称。 longname(完整名称): 安全组子节点的完整名称。 parentshortname(父节点简称): 安全组子节点所属的父节点的简称。 标签(LABEL) 通过MLSCLSCREATELABEL()函数创建或替换MLS 策略的标签(label),并将其存储到数据库中。 SQL SELECT MLSCLSCREATELABEL(policyname, labelid, labelstr) 参数描述: policyname(策略名称): 指定要添加标签的策略名称。 labelid(标签ID): 用于标识标签的唯一ID,取值范围[0, 32767]。 labelstr(标签名): 标签,不可为空,长度不超过256。由 ,其compartmentids和groupids由1到N个ID构成,ID间用,分割。有效的表达形式如下: levelid:compartmentid1,compartmentid2,...compartmentidN:groupid1,groupid2,...groupidN levelid:compartmentid:groupid levelid:compartmentid: levelid::groupid levelid:: 表标签绑定 通过MLSCLSCREATETABLELABEL()函数将指定标签绑定到指定的表(Table),并将相关数据存储到pgclstable系统表。 SQL SELECT MLSCLSCREATETABLELABEL(policyname labelid, schemaname, tablename) 参数描述: policyname(策略名称): 指定要应用的策略名称。 labelid(标签ID): 要应用于表的标签ID,取值范围[0, 32767]。 schemaname(模式名称): 表所在的模式名。 tablename(表格名称): 要应用标签的表名。 通过MLSCLSDROPTABLELABEL()函数删除绑定到表上的标签并更新pgclstable系统表数据。 SQL MLSCLSDROPTABLELABEL(policyname, schemaname, tablename) 用户标签绑定/删除 通过MLSCLSCREATEUSERLABEL()函数为指定的用户创建一个带有默认标签的用户账户,并将其存储到 pgclsuser 表中。 SQL SELECT MLSCLSCREATEUSERLABEL(policyname, username name, defreadlabel, defwritelabel, defrowlabel) 参数描述: policyname(策略名称): 指定要应用的策略名称。 username(用户名): 要创建标签的用户账户名称。 defreadlabel(默认读标签): 为用户定义的默认读标签ID。 defwritelabel(默认写标签): 为用户定义的默认写标签ID。 defrowlabel(默认行标签): 为用户定义的默认行标签ID。 通过MLSCLSDROPUSERLABEL()函数为指定用户删除标签,并将pgclsuser 表中指定用户的标签删除,且断开指定用户当前所有的数据库连接。 SQL SELECT MLSCLSDROPUSERLABEL(username) 参数描述: username(用户名): 要删除指定用户标签的用户账户名称。 示例: 初始化环境 SQL c mlsadmin 创建安全策略 select MLSCLSCREATEPOLICY('rlspolicy', 66); 创建安全等级 select MLSCLSCREATELEVEL('rlspolicy', 10, 'defaultlevel', 'default Level'); select MLSCLSCREATELEVEL('rlspolicy', 10, 'userlevel', 'user Level'); select MLSCLSCREATELEVEL('rlspolicy', 9, 'badlevel', 'bad Level'); select MLSCLSCREATELEVEL('rlspolicy', 100, 'goodlevel', 'good Level'); 创建隔离区 select MLSCLSCREATECOMPARTMENT('rlspolicy', 30, 'rlscom0', 'RLS compartment 0'); select MLSCLSCREATECOMPARTMENT('rlspolicy', 31, 'rlscom1', 'RLS compartment 1'); select MLSCLSCREATECOMPARTMENT('rlspolicy', 32, 'rlscom2', 'RLS compartment 2'); 创建安全组 select MLSCLSCREATEGROUPROOT('rlspolicy', 50, 'root', 'group root'); select MLSCLSCREATEGROUPNODE('rlspolicy', 51, 'child1', 'child of root node 1', 'root'); select MLSCLSCREATEGROUPNODE('rlspolicy', 52, 'child2', 'child of root node 2', 'root'); select MLSCLSCREATEGROUPNODE('rlspolicy', 511, 'child11', 'child of child1 node 1', 'child1'); select MLSCLSCREATEGROUPNODE('rlspolicy', 512, 'child12', 'child of child1 node 2', 'child1'); 创建安全标签,此时和安全等级,隔离区以及安全组进行绑定 select MLSCLSCREATELABEL('rlspolicy', 1024, 'defaultlevel:rlscom0:child12'); 将标签绑定到表 alter table public.tbl1 add column cls clsitem default '99:1024'; select MLSCLSCREATETABLELABEL('rlspolicy', 1024, 'public', 'tbl1'); 安全等级 SQL select MLSCLSCREATELABEL('rlspolicy', 1025, 'userlevel::'); select MLSCLSCREATELABEL('rlspolicy', 1026, 'badlevel::'); select MLSCLSCREATELABEL('rlspolicy', 1027, 'goodlevel::'); 将标签绑定到用户 select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike1', 1024, 1024, 1024); select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike2', 1025, 1025, 1025); select MLSCLSCREATEUSERLABEL('rlspolicy', 'badgodlike1', 1026, 1026, 1026); select MLSCLSCREATEUSERLABEL('rlspolicy', 'goodgodlike1', 1027, 1027, 1027); SQL c godlike1 insert into public.tbl1 select generateseries(1,3), generateseries(1,3); select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:1024 2 2 66:1024 3 3 66:1024 (3 rows) SQL c godlike2 insert into public.tbl1 select generateseries(4,6), generateseries(4,6); 当前用户不在隔离区,无法看到godlike1用户创建的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 4 4 66:1025 5 5 66:1025 6 6 66:1025 (3 rows) SQL c badgodlike1 低优先级的用户无法看到高优先级的用户插入的数据 select from public.tbl1 order by col1; col1 col2 cls ++ (0 rows) SQL insert into public.tbl1 select generateseries(7,9), generateseries(7,9); 低优先级用户可以看到自己创建的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 7 7 66:1026 8 8 66:1026 9 9 66:1026 (3 rows) SQL c goodgodlike1 高优先级用户可以看到低优先级用户创建的数据 同时无法看到隔离区的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 4 4 66:1025 5 5 66:1025 6 6 66:1025 7 7 66:1026 8 8 66:1026 9 9 66:1026 (6 rows) SQL insert into public.tbl1 select generateseries(10,12), generateseries(10,12); select from public.tbl1 order by col1; col1 col2 cls ++ 4 4 66:1025 5 5 66:1025 6 6 66:1025 7 7 66:1026 8 8 66:1026 9 9 66:1026 10 10 66:1027 11 11 66:1027 12 12 66:1027 (9 rows) SQL c godlike1 高优先级用户可以看到比自己低优先级用户创建的数据 无法看到比自己优先级高的用户创建的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:1024 2 2 66:1024 3 3 66:1024 4 4 66:1025 5 5 66:1025 6 6 66:1025 7 7 66:1026 8 8 66:1026 9 9 66:1026 (9 rows) SQL c commonuser0 select from public.tbl1 order by col1; col1 col2 cls ++ (0 rows) 安全隔离区 SQL c mlsadmin select MLSCLSDROPUSERLABEL('godlike1'); select MLSCLSDROPUSERLABEL('godlike2'); select MLSCLSDROPUSERLABEL('badgodlike1'); select MLSCLSDROPUSERLABEL('goodgodlike1'); 创建安全标签,并绑定隔隔离区 select MLSCLSCREATELABEL('rlspolicy', 2048, 'defaultlevel:rlscom0:'); select MLSCLSCREATELABEL('rlspolicy', 2049, 'defaultlevel:rlscom0,rlscom1,rlscom2:'); select MLSCLSCREATELABEL('rlspolicy', 2050, 'defaultlevel:rlscom1,rlscom2:'); select MLSCLSCREATELABEL('rlspolicy', 2051, 'defaultlevel:rlscom0,rlscom2:'); 将标签绑定到用户 select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike1', 2048, 2048, 2048); select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike2', 2049, 2049, 2049); select MLSCLSCREATEUSERLABEL('rlspolicy', 'badgodlike1', 2050, 2050, 2050); select MLSCLSCREATEUSERLABEL('rlspolicy', 'goodgodlike1', 2051, 2051, 2051); SQL c godlike1 insert into public.tbl1 select generateseries(1,3), generateseries(1,3); select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:2048 2 2 66:2048 3 3 66:2048 (3 rows) SQL c godlike2 insert into public.tbl1 select generateseries(4,6), generateseries(4,6); 当前用户所在隔离区含godlike1用户隔离区,可以看到godlike1的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:2048 2 2 66:2048 3 3 66:2048 4 4 66:2049 5 5 66:2049 6 6 66:2049 (6 rows) SQL c badgodlike1 insert into public.tbl1 select generateseries(7,9), generateseries(7,9); 当前用户所在隔离区无法包含前面用户的隔离区,无法看到他们插入的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 7 7 66:2050 8 8 66:2050 9 9 66:2050 (3 rows) SQL c goodgodlike1 insert into public.tbl1 select generateseries(10,12), generateseries(10,12); 相同等级,godlike1的隔离区是当前的子集,当前用户可以看到godlike1插入的数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:2048 2 2 66:2048 3 3 66:2048 10 10 66:2051 11 11 66:2051 12 12 66:2051 (6 rows) SQL c godlike2 当前用户含rlscom0,rlscom1,rlscom2三个隔离区可以看到之前插入的所有数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:2048 2 2 66:2048 3 3 66:2048 4 4 66:2049 5 5 66:2049 6 6 66:2049 7 7 66:2050 8 8 66:2050 9 9 66:2050 10 10 66:2051 11 11 66:2051 12 12 66:2051 (12 rows) 安全组 SQL c mlsadmin select MLSCLSDROPUSERLABEL('godlike1'); select MLSCLSDROPUSERLABEL('godlike2'); select MLSCLSDROPUSERLABEL('badgodlike1'); select MLSCLSDROPUSERLABEL('goodgodlike1'); 创建安全标签,并绑定用户组 select MLSCLSCREATELABEL('rlspolicy', 4096, 'defaultlevel:rlscom0:root'); select MLSCLSCREATELABEL('rlspolicy', 4097, 'defaultlevel:rlscom0:child1'); select MLSCLSCREATELABEL('rlspolicy', 4098, 'defaultlevel:rlscom0:child11,child12'); 将标签绑定到用户 select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike1', 4096, 4096, 4096); select MLSCLSCREATEUSERLABEL('rlspolicy', 'godlike2', 4097, 4097, 4097); select MLSCLSCREATEUSERLABEL('rlspolicy', 'badgodlike1', 4098, 4098, 4098); SQL c badgodlike1 insert into public.tbl1 select generateseries(1,3), generateseries(1,3); select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:4098 2 2 66:4098 3 3 66:4098 (3 rows) SQL c godlike2 insert into public.tbl1 select generateseries(4,6), generateseries(4,6); 安全组根节点可以看到子节点数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:4098 2 2 66:4098 3 3 66:4098 4 4 66:4097 5 5 66:4097 6 6 66:4097 (6 rows) SQL c godlike1 insert into public.tbl1 select generateseries(7,9), generateseries(7,9); 安全组根节点可以看到所有子节点数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:4098 2 2 66:4098 3 3 66:4098 4 4 66:4097 5 5 66:4097 6 6 66:4097 7 7 66:4096 8 8 66:4096 9 9 66:4096 (9 rows) SQL c badgodlike1 子节点 无法看到根节点数据 select from public.tbl1 order by col1; col1 col2 cls ++ 1 1 66:4098 2 2 66:4098 3 3 66:4098 (3 rows)