0801-什么是Apache Ranger - 4 - Resource vs Tag Based Policies

2020-08-20 10:00:10 浏览数 (1)

作者:Eric Lin (林晨辉), Cloudera高级售后技术支持工程师。

这里输入标题

在阅读本文前,建议先阅读前面的文章:

《0741-什么是Apache Ranger - 1》

《0742-什么是Apache Ranger - 2》

《0745-什么是Apache Ranger - 3》

在前面的文章中,我们介绍了为什么Ranger会替代Sentry,Ranger的基础架构以及2.0引入的新功能安全区域(Security Zone)功能。本文主要是通过一些例子介绍基于标签的策略和基于资源的策略的区别。

为了介绍Ranger中基于标签的策略,我们需要了解什么是Apache Atlas,因为Ranger依靠Atlas获取有关Tag的元数据信息,然后才能决定如何应用策略。

以下摘自Apache Atlas官网:

Atlas是一组可扩展的核心基础治理服务,使企业能够高效的满足Hadoop中的合规性要求,并允许与整个企业数据生态系统集成。 Apache Atlas为组织提供开放的元数据管理和治理功能,以建立数据资产目录,对这些资产进行分类和治理,并为数据科学家,分析师和数据治理团队提供围绕这些数据资产的协作功能。 https://atlas.apache.org/#/

它提供以下主要功能:

  • Metadata types & instances
  • Classification
  • Lineage
  • Search/Discovery
  • Security & Data Masking

前两个是Ranger需要的主要功能,本文后面的示例中会有更多内容进行介绍,建议花一点时间先了解一下Atlas。

现在,我们对Atlas是什么有了一些了解,让我们回到Ranger中基于资源和标签的策略。基于资源定义的策略,可以是Hive表,HDFS路径,Kafka topic等。

对于基于标签的策略,没那么容易描述,总结功能如下:

  • 将资源分类与访问授权分开
  • 一种策略可以应用于HDFS,Hive,Kafka等中的资源,而无需更新单个资源
  • 标签(分类)在Atlas中创建,并附加到元数据(列,表,HDFS路径等)
  • Ranger TagSync(消费者)可用于通过Kafka(topic名称ATLAS_ENTITIES)将标签存储与Apache Atlas(生产者)同步。
  • 每个服务的plugin将标签信息保存到本地的policyCache中,以便快速检索

我将通过一个非常基本的示例来演示Ranger中基于资源和标记的策略的工作方式,我们将从基于资源的策略开始,以设置一些规则来阻止用户访问表中的某些列,然后使用基于标签的策略为某些用户打开访问权限。

首先我创建一张student表包含以下字段:

代码语言:javascript复制
CREATE TABLE student (
  id int,  
  name string, 
  age int, 
  address string, 
  dob date
);

然后插入几条记录:

代码语言:javascript复制
INSERT INTO student VALUES 
  (1, "Student 1", 21, "Address for Student 1", '2000-01-01'), 
  (2, "Student 1", 22, "Address for Student 2", '2000-01-02'), 
  (3, "Student 1", 23, "Address for Student 3", '2000-01-03'), 
  (4, "Student 1", 24, "Address for Student 4", '2000-01-04'), 
  (5, "Student 1", 25, "Address for Student 5", '2000-01-05');

由于我将表放在default database下,默认情况下,Ranger将允许用户通过“default database tables columns”策略访问default数据库下的所有表。

这意味着我的设置用户“ user1”和“ user2”将自动拥有对该表的完全访问权限:

我将禁用此默认策略,并创建一个新策略,该策略将限制对“ address”和“ dob”列的访问,因为我不希望每个人都能看到所有学生的地址和出生时间 。

要创建基于资源的策略,需要进入Access Manager > Resource Based Policies,选择分配给资源的正确安全区域( Security Zone),然后单击Hive存储库和“New Policy”。新的PII示例策略如下所示:

你可以能已经注意到,我为“address” 和 “dob” 列选择了 “exclude”。这样我只需要选择需要exclude的列,假如table有很多column,这样比较方便。因为我的student表字段不多,其实你也可以“include”其他3个column,但最终结果是一致的。

现在如果我“Select”“address”或“dob”字段,访问将被拒绝:

根据上面的示例我通过基于资源的策略设置一张table对user1和user2两个用户隐藏了两列,因为这两列被视为PII信息,我们不希望所有人 能够访问它们。下面我将切换为基于标签的策略来设置仅让user1能访问所有的列。

开始Hive表可能尚未导入到Atlas的元数据系统中,这可能是由于是先安装设置了Hive,然后才安装设置Atlas,如果要触发初始导入,可以运行以下脚本:

代码语言:javascript复制
$ bash /opt/cloudera/parcels/CDH/lib/atlas/hook-bin/import-hive.sh
Using Hive configuration directory [/etc/hive/conf]
/etc/hive/conf:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop/lib/*:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop/.//*:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-hdfs/./:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-hdfs/lib/*:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-hdfs/.//*:/opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/.//*:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-yarn/./:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-yarn/lib/*:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/hadoop/libexec/../../hadoop-yarn/.//*
Log file for import is /opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/lib/atlas/logs/import-hive.log
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/jars/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-7.0.3-1.cdh7.0.3.p0.1635019/jars/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
Enter username for atlas :- admin
Enter password for atlas :-
Hive Meta Data imported successfully!!!

提示输入Atlas用户名和密码后,然后等待其完成即可。我这儿使用的是CDP,如果你仍然在使用HDP,则脚本再以下位置:

代码语言:javascript复制
/usr/hdp/current/atlas-server/hook-bin/import-hive.sh

导入完成后,你可以登录Atlas并从左侧导航面板搜索student table,如下所示:

我们首先要做的是创建一个分类(Classification),该Classification位于左侧面板上“Search”菜单的旁边,单击它,然后单击 号,输入以下信息:

现在,我们已经创建了Tag/Classification,让我们回到“student”表,然后将Classification添加到我们标识为PII的列中,即“address”和“dob”。只需再次搜索“student”,然后在返回的结果中单击“student”链接。不用担心其他信息,只需直接进入“Schema”标签:

然后单击“address”和“dob”列的 按钮,选择PII分类,然后单击“Add”按钮:

完成后,页面看起来应该如下所示:

这样就完成了Atlas这边的设置,我们在其中启用了“address”和“ dob”列的PII Tag/Classification。接下来我们在Ranger Web UI中设置基于标签的策略。进入“ Ranger”>“ Access Manager”>“ Tag Based Policies”,确保你位于正确的Security Zone之下,单击“ cm_tag”,这个标签会在安装的时候默认创建,但名称可能略有不同,然后单击“Add New Policy”:

在“Allow Conditions”下的“Select User”列中添加“ user1”:

在Component Permissions之下,选择具有“SELECT”权限的Hive服务:

完成上述更改后,需要等待几秒钟以让Ranger同步更改,然后再次使用user1运行查询,现在会允许查询“ address”和“ dob”字段:

但user2用户的查询访问依旧会受到限制:

至此我们已经完成了对Student表的完整设置,允许user1访问所有数据,但是user2受基于资源和基于标记的策略的部分限制。为了进一步展示基于标签的策略的功能,我会创建另外一张表“ student_result”,该表的访问完全受到限制,但我们不需要创建其他的策略,只需要到Atlas中进行一些小的更改。

代码语言:javascript复制
CREATE TABLE student_result (
  id int, 
  student_id int, 
  subject string, 
  score int
);

等待元数据同步到Atlas,你可以登录到Atlas然后搜索“ student_result”表进行确认:

现在,我们将在table级别为“ student_result”应用“ PII”分类,只需单击屏幕截图上方显示的“Classification”选项卡,然后单击 按钮并选择“ PII”,如下所示:

在通过TagSync将Atlas中的更新同步到Ranger,并且HiveServer2客户端更新其本地缓存之后,我们可以使用两个用户再次运行同一查询,可以发现user2没有访问权限,但是user1拥有访问权限,因为已授予“ user1” 访问PII标签,该标签已在table级别分配给student_result:

代码语言:javascript复制
$ kinit user1
0: jdbc:hive2://hive2.com>select * from student_result;
 -------------------- ---------------------------- ------------------------- ----------------------- 
| student_result.id  | student_result.student_id  | student_result.subject  | student_result.score  |
 -------------------- ---------------------------- ------------------------- ----------------------- 
| 1                  | 1                          | Math                    | 80                    |
 -------------------- ---------------------------- ------------------------- ----------------------- 

$ kinit user2
0: jdbc:hive2://hive2.com> select * from student_result;
Error: Error while compiling statement: FAILED: HiveAccessControlException Permission denied: user [user2] does not have [SELECT] privilege on [default/student_result/*] (state=42000,code=40000)

你可以看到我们没有创建任何新策略来授予对新表“ student_result”的访问权限,我们只是将Tags/Classifications附加到目标表,并且在Ranger中定义的相同Tag Policy就生效了。

到目前为止,我们仅限于访问Hive,现在我们还将相同的Tag Policy应用于HDFS路径,以表明同样适用。先使用hdfs超级用户创建一个/data/pii目录:

代码语言:javascript复制
kinit hdfs
hdfs dfs -mkdir /data/pii

确认user1和user2两个用户都无法访问这个新目录:

代码语言:javascript复制
[user1@c2393-node2 ~]$ hdfs dfs -mkdir /data/pii/user1
mkdir: Permission denied: user=user1, access=WRITE, inode="/data/pii":hdfs:hdfs:drwxr-xr-x

[user2@c2393-node3 ~]$ hdfs dfs -mkdir /data/pii/user2
mkdir: Permission denied: user=user2, access=WRITE, inode="/data/pii":hdfs:hdfs:drwxr-xr-x

请记住,当前我不认为HDFS路径会自动同步到Atlas,因此我们需要在Atlas Web UI中手动创建/data/pii目录。转到主页,然后单击“Create New Entity”链接:

然后,为“Name”字段输入目录的简短版本,为目录的完整版本输入完整的路径,包括Path字段带有hdfs//前缀的NameNode/Namespace,并添加“ @ {clustername}”以在Atlas中为QualifiedName唯一标识此实体。请注意,QualifiedName必须是唯一的。存后,转到该实体的“Classifications”选项卡,然后跟之前一样在“Classifications”菜单下添加PII。如下所示:

之前我们为PII设置标签策略时,我们仅在策略创建页面上选择了“ Hive”服务。因此,我们需要返回之前创建的标签策略,更新该策略以包括“ HDFS”服务:

保存后,我们可以在Allow Conditions的Component Permissions中看到HDFS:

需要记住的另一件事是,我们需要确保创建的Tag Policy应与分配给Security Zone的资源匹配。在本文的例子中,我没有在任何Security Zone中进行设置,所以是可以的。但是在真实的环境中,需要仔细检查并确保HDFS目录被分配给Tag Policy所属的Security Zone的资源所覆盖。

完成后使用用户user1在/data/pii下创建子文件夹成功,但是user2仍然不能:

代码语言:javascript复制
$ kinit user1
$ hdfs dfs -mkdir /data/pii/user1
$ hdfs dfs -ls /data/pii
Found 3 items
drwxr-xr-x   - user1 hdfs          0 2020-03-25 22:01 /data/pii/user1

$ kinit user2
$ hdfs dfs -mkdir /data/pii/user2
mkdir: Permission denied: user=user2, access=WRITE, inode="/data/pii":hdfs:hdfs:drwxr-xr-x

同样,我们没有创建任何新的Ranger策略,我们所做的只是

  • 更新现有的标签策略以包括HDFS服务
  • 在Atlas中创建新的HDFS实体并附加PII标签

这样可以最大程度地减少我们需要保留的策略数量,并使系统更易于维护。如果你有兴趣,可以继续练习将相同的Tag应用于HBase,Kafka等。

最后,请注意基于标签的策略将在基于资源的策略之前进行判断,因此在进行故障排查期间,请确保执行正确的检查顺序。具体见下图所示:

原文参考:

代码语言:javascript复制
https://cloudera.ericlin.me/2020/03/introduction-to-apache-ranger-part-iv-resource-vs-tag-based-policies/

0 人点赞