Zeppelin集成Ranger实现用户权限管控

前言

在Hadoop生态中,典型的鉴权方案:
1、LDAP+Kerberos+Sentry
主要应用在CDH平台,支持 Hive、Impala、HDFS 等主流组件,不支持 Hbase、Yarn、Kafka、Storm等常见组件。

2、LDAP+Kerberos+Ranger
主要应用在Apache Hadoop或HDP平台,- 支持组件丰富,如 HDFS、HBase、Hive、Yarn、Kafka、Storm 等,提供丰富Rest Api,且集成其他组件相对容易。

实际运行过程中,Kerberos解决的场景:

  • 服务认证过程有效地防止 broker datanode regionserver 等组件冒充加入集群
  • 解决了服务端到服务端的认证的同时也解决了客户端到服务端的认证

但它同时也存在短板,服务认证过程中为了安全性使用临时 ticket,认证信息会失效,用户多的情况下重新认证比较繁琐,对于服务而言太重了,也给运维过程带来比较多工作量。数据沙盒安全管控项目使用场景上更侧重于用户空间使用隔离,服务认证方面不是非常必须,Ranger自带的用户体系及权限管理控制服务能满足全部鉴权要求,理论上可以舍弃LDAP+Kerberos。

那么Ranger是怎么在HDFS上工作的呢?
在这里插入图片描述
对于 HDFS/YARN 这两者服务,默认打开Ranger鉴权模型后,先走Ranger策略,如果Ranger策略中没有相应策略,那么默认走底层 HDFS/YARN 自身的权限控制。即HDFS ACL和YARN自带的<用户-属组>提交队列鉴权。

方案设计说明

当前数据沙盒项目主要以Zeppelin作为服务入口,数据同步到HDFS后,无需维护表schema信息,用户直接使用sparksql读写文件,极为方便,且Zeppelin自身支持各种各样Interpreter使用,远比Hue使用场景更广。因此方案设计之初确定调研方向为Zeppelin+Ranger:
权限控制链路:

  • Zeppelin --> Ranger认证 --> HDFS文件
  • Zeppelin --> LDAP --> Ranger认证 --> HDFS文件

方案1:经咨询Apache Zeppelin PMC,目前Zeppelin社区没有直接集成Ranger案例,需开发实现用shrio适配ranger,对于笔者而言集成难度大,暂时不予考虑。
方案2:因Zeepelin shiro配置支持LDAP作为用户/组管理,Ranger也支持LDAP作为用户/组管理,所以将LDAP作为Zeepelin <–> Ranger之间的桥梁,实现用户/组集中管理,可行性高。

基于此,以下为方案2的实现过程:

  • LDAP安装配置
  • Zeppelin集成LDAP
  • Ranger安装与集成LDAP

本文中的所有操作实现均在AWS EMR上

一、LDAP安装配置

AWS EMR 操作系统镜像为Amazon Linux AMI release 2018.03,此系统镜像基于Centos6.x封装,安装不了FreeIPA,若能安装FreeIPA,能极大地提高OpenLDAP与LDAPadmin安装与运维过程效率。

安装配置过程参考笔者其他博文

二、Zeppelin集成LDAP

1、修改zeppelin-site.xml

<property>
  <name>zeppelin.anonymous.allowed</name>
  <value>false</value>
  <description>Anonymous user allowed by default</description>
</property>

2、配置shiro.ini

[users]

[main]
ldapRealm = org.apache.zeppelin.realm.LdapRealm
ldapRealm.contextFactory.url = ldap://ip-172-16-15-101:389

# 搜索人匹配: uid={0} 也可以是 cn={0},具体看 ldap 中怎么配置user
ldapRealm.userDnTemplate = uid={0},ou=People,dc=pupu,dc=com

ldapRealm.contextFactory.authenticationMechanism = simple

# ldap管理账号
ldapRealm.contextFactory.systemUsername= cn=Manager,dc=pupu,dc=com

# ldap管理账户密码
ldapRealm.contextFactory.systemPassword= Aojf+pupuni123

ldapRealm.pagingSize = 200
ldapRealm.authorizationEnabled=true
ldapRealm.searchBase = dc=pupu,dc=com

# 在 ou=People 域下面查找
ldapRealm.userSearchBase = ou=People,dc=pupu,dc=com

# dc=pupu,dc=com 是根目录,ou=group 是一个分支,意思在 Group 组下面查找
ldapRealm.groupSearchBase = ou=Group,dc=pupu,dc=com

# 创建 ldap 组的类名
ldapRealm.groupObjectClass= posixGroup

ldapRealm.userLowerCase = true
ldapRealm.userSearchScope = subtree;
ldapRealm.groupSearchScope = subtree;

# 如果为true的话 ,不使用 groupSearchFilte r配置的匹配条件 
ldapRealm.groupSearchEnableMatchingRuleInChain = true

# 第一个 admin 是 ldap 上的组的名字,第二个 admin 是 zeppelin 中role的名字(即管理员角色),若是有多个组映射以逗号隔开
ldapRealm.rolesByGroup = admin: admin

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = JSESSIONID
cookie.httpOnly = true
# cookie.secure = true
sessionManager.sessionIdCookie = $cookie
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000
shiro.loginUrl = /api/login
[roles]
role1 = *
admin = *
[urls]
/api/interpreter/setting/restart/** = authc
/api/interpreter/** = authc, roles[admin]
/api/configurations/** = authc, roles[admin]
/api/credential/** = authc, roles[admin]
/** = authc

这里特别注意一个参数:

ldapRealm.rolesByGroup = admin: admin

意思是admin组中的所有ldap用户都是zeppelin 管理员role,admin的ldif如下:

dn: cn=admin,ou=Group,dc=pupu,dc=com
objectClass: posixGroup
objectClass: top
cn: admin
gidNumber: 510

可以通过ldapsearch看到这个组中包含admin用户,即zeppelin管理员,admin用户的ldif:

# admin, People, pupu.com
dn: uid=admin,ou=People,dc=pupu,dc=com
uid: admin
cn: admin
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {SSHA}cDf+JEg19iFsOlf4B1BSpE0FWbHMo5cU
shadowMin: 0
shadowMax: 99999
shadowWarning: 0
loginShell: /bin/bash
uidNumber: 510
gidNumber: 510
homeDirectory: /home/admin

3、验证

使用phpLDAPadmin将admin用户memberOf加到admin组,按照前面<1~2>步骤配置完,启动后使用admin用户登录,发现无法进入创建Interpreter页面,即没有admin权限,查看日志

LoginRestApi.java[postLogin]:206) - {"status":"OK","message":"","body":{"principal":"admin","ticket":"227fb9e2-2833-48a5-92c2-9fb94d50db6d","roles":"[]"}}

从日志可以看出roles为空,说明ldap group和zeppelin role没有映射成功,查看zeppelin LdapRealm这部分代码,发现zeppelin到ldap中拉取组信息时使用的检索表达式为:

(&amp;(objectClass=posixGroup)(member:1.2.840.113556.1.4.1941:=uid=admin))

因为ldap组中使用memberUid保存用户的uid,所以这个表达式是无法检索到组信息,也就无法完成ldap group和zeppelin role的绑定。尝试过在shiro中将ldapRealm.groupSearchEnableMatchingRuleInChain参数项改成false,添加:ldapRealm.groupSearchFilter = (&(objectclass=posixGroup)(memberUid=uid={0},ou=People,dc=pupu,dc=com))以实现自定义搜索组信息,依旧无法检索到组信息,最后只能以如下修改zeppelin LdapRealm代码解决此问题。

4、解决方法

修改源码
org.apache.zeppelin.realm.LdapRealm

# 第一处修改
private static final String MATCHING_RULE_IN_CHAIN_FORMAT =
        "(&amp;(objectClass=%s)(%s))";
        
# 第二处修改
searchResultEnum = ldapCtx.search(
        getGroupSearchBase(),
        String.format(
                MATCHING_RULE_IN_CHAIN_FORMAT,
                groupObjectClass,
                userDn.replace("uid","memberUid")),
        searchControls);

重新打包

 # nohup mvn clean package -pl zeppelin-server -Denforcer.skip  -Dcheckstyle.skip -DskipRat -DskipTests > maven.log &;

编译时带上参数:-Denforcer.skip -Dcheckstyle.skip -DskipRat,不然mvn build过程会出错,编译完成后拷贝zeppelin-server

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值