简介:本文将向大家介绍伴鱼大数据权限系统的设计与实现。
伴鱼早期,整个大数据仓库下的数据基本处于裸奔状态,没有做任何的权限校验与审计,用户可以对数据为所欲为,这个阶段主要考虑效率优先。
随着业务的发展,数据安全的重要性愈发突显,大数据权限系统因运而生,本文将向大家介绍伴鱼大数据权限系统的设计与实现。
在伴鱼,离线数仓下的数据主要有以下几种访问方式:
上述几类访问方式对应的访问渠道主要有以下几种:
管控与效率两者之间是天然对立的,我们需要做的是在这之间寻求一种平衡。就目前的形式来看,我们期望达到以下目标:
权限管控主要体现在两个方面:用户认证(authentication)与权限认证(authorization)。
大数据各组件支持不同的用户认证方式,这里主要看下我们所关注的组件支持的认证方式。
可见统一基于 Kerberos 的方式,可以实现全链路的用户认证。Kerberos 是一个集中式的用户认证管理框架,具备较完备的用户认证能力,但整体运维成本较高,这与我们的期望(尽可能少的引入新的组件)相悖,因此决定采用 LDAP 的方式(目前已具备实操、运维的经验)。也就意味着我们只是在 Hadoop 组件之上进行用户认证,Hadoop 的各组件依旧保持没有任何的用户认证,用户可以在机器节点上伪装任意用户对集群中的数据进行操控,而这类方式对于非开发人员具有一定的门槛,因此也符合我们的设计目标。
当前数据链路各组件的关系以及权限控制如下图所示:
我们在 Hive 的 HiveServer2 和 Presto 的 Coordinator 组件上进行了用户认证和授权,而在 HDFS 的 NameNode 组件只进行了授权。注意到,在授权流程中 Ranger Plugin 依赖了 Hadoop Group Mapping,而它又依赖了 LDAP,关于这些关系将在下文中阐述。
用户认证即对请求中的用户名、密码进行校验,逻辑相对简单。只需对相应的组件进行简单的配置即可,如下是 HiveServer2 组件配置示例:
<property>
<name>hive.server2.authentication</name>
<value>LDAP</value>
</property>
<property>
<name>hive.server2.authentication.ldap.baseDN</name>
<value>ou=People,dc=ipalfish,dc=com</value>
</property>
<property>
<name>hive.server2.authentication.ldap.url</name>
<value>ldap://*****:389</value>
</property>
<property>
<name>hive.server2.authentication.ldap.userDNPattern</name>
<value>cn=%s,ou=bigdata_user,ou=People,dc=ipalfish,dc=com</value>
</property>
用户和用户组是权限认证的基本对象,引入用户组的目的是为了提升效率。设想这么一个场景:一批用户需要同一批库表的权限,最直接的想法是每一个用户都申请一遍权限,从算法的角度看,时间复杂度是 O(N) 的。如果可以抽象出用户组的概念,这批用户加入同一个用户组,同时保证组内的成员可以继承组的所有权限,那么就可以只为用户组申请一次权限即可,时间复杂度降到了 O(1)。
Ranger 中 User 对应用户,Group 对应用户组,一个用户可以加入多个组,它实现了 User 继承 Group 权限的特性。权限认证时判定一项策略是否通过,会判定用户的 User 或用户所属的任意一个 Group 是否在策略中配置,如有则通过。这里引申出一个问题,用户所属的 Groups 如何获取?
查阅代码,不难发现使用 Hadoop 的 Hadoop Groups Mapping 机制。下图为 ranger presto plugin 部分代码片段:
private RangerPrestoAccessRequest createAccessRequest(RangerPrestoResource resource, SystemSecurityContext context, PrestoAccessType accessType) {
String userName = null;
Set<String> userGroups = null;
if (useUgi) {
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(context.getIdentity().getUser());
userName = ugi.getShortUserName();
String[] groups = ugi != null ? ugi.getGroupNames() : null;
if (groups != null && groups.length > 0) {
userGroups = new HashSet<>(Arrays.asList(groups));
}
} else {
userName = context.getIdentity().getUser();
userGroups = context.getIdentity().getGroups();
}
RangerPrestoAccessRequest request = new RangerPrestoAccessRequest(
resource,
userName,
userGroups,
accessType
);
return request;
}
可以看出,使用了 org.apache.hadoop.security 包下的 UserGroupInformation 信息,这即是 Hadoop Groups Mapping 相关的实现代码。Hadoop Groups Mapping 支持 LDAP 的方式获取 User 和 Group 信息,我们也采用了这种方式,因此上文中提到的用户认证流程和授权流程最终都将依赖 LDAP。
一个数据表的不同的列具有不同的信息价值和数据敏感度,因此需要为每一列都划分一个权限等级,用户申请权限是按照列的粒度进行申请。不同的权限等级对应着不同的权限审批流程,目前我们划分了三种权限等级:P0、P1 和 P2,级别由高到低,P0 级别的列信息最敏感,因此拥有最长的审批流程。
Ranger 的策略类型主要有两种:Access 和 Mask。
注:所有在 Ranger Admin 配置的策略将由 Ranger Plugin 中的线程定期 Pull 至组件,并在运行时执行权限认证。
下图展示了在权限系统申请库 test 表 tb 下字段名为 tid 的权限时对应的 Ranger 策略示例:
权限申请工单
Access Policy
Mask Policy
以上从原理层面介绍了基于 Ranger 进行权限认证的几个重要概念,通过修改相关组件的配置,即可使权限认证生效。本节将从平台的角度看一下如何生成 Ranger 中的策略配置。
首先需要考虑权限策略初始化的问题。一张 Hive 表的权限策略必然是在表创建之后生成的,我们期望表创建时创建者能够直接指定各列对应的权限等级,同时创建者作为表的 Owner 直接拥有表所有列的全部权限。主要可以从两个方向考虑:
CLI:指代 Beeline。由于并未完全约束用户在建模平台建表,开发人员可以直接在自己脚本中通过 CLI 直接建表,这种情况下表的元信息是缺失的。
我们很难将所有渠道统一起来,即便最终建表行为可以收敛至建模平台,但从系统边界的角度考虑,建模和权限分属两个系统,权限策略的创建应当收敛至权限系统。
异步创建
异步化创建的方式需要借助消息队列,需要将所有的建表事件投递至一个 Topic,权限系统后台监听此 Topic 消息,从而触发策略的初始化。那么如何捕捉全部的建表事件并投递至一个消息队列?这就需要借助我们提供的「元数据中心」平台,它统一管理了全部数据的元信息。我们的「元数据中心」平台是在 Apache Atlas 基础上搭建的。Apache Atlas 通过其提供的各类组件的 Atlas Hook 以此来捕捉元信息。以 Atlas Hive Hook 为例,我们提交给 Hive 的建表信息包括附加的元信息都可以在此 Hook 中被捕捉,这些信息紧接着会被发送至 Atlas Server 进行存储,与此同时 Atlas Server 可以通过配置一个对外的 Topic 统一将这些消息发送至外部的监听系统。通过这种机制,我们就达到异步初始化权限策略的目的。
值得一提的是,字段权限等级的修改有且仅能在元数据中心进行,等级的修改将影响到对应的权限策略。对于这一事件,将通过同样的方式,被权限系统后台监听,并触发相应的动作。
整个过程如下图所示:
大数据权限系统主要划分为三部分:
BI 系统可以说得上是一家公司使用最频繁的一款数据产品,数据开发工程师、分析师在上面开发报表,产品、运营等业务方在上面查看报表。我们的 BI 系统是基于开源的 Metabase 搭建的,前文提到,Metabase 自身具备一套权限管控的机制,但实践下来十分难用且由于没有审批工单机制,往往需要人工线下确认,增加了沟通的成本。同时审批工作都由管理员完成,十分耗费个人的人力成本。基于此,我们决定在权限系统中整合 Metabase 相关的权限操作。
Metabase 报表权限申请工单示例:
本文阐述伴鱼大数据权限系统的核心设计要点,目前 Presto、Hive、HDFS、Metabase的权限都得到了收敛,工单化的申请流程极大的降低了授权申请的成本,自动化程度比较高,效果比较理想。
来源:伴鱼技术部