使用 Kerberos
Ranger 与 Kerberos 都是 Hadoop 下与数据安全密不可分的组件,简而言之,Ranger 提供了创建“哪些用户能够访问哪些文件”的安全规则的能力,而 Kerberos 则解决了用户认证的问题。二者可以搭配使用以获得最佳的数据安全性,也可以单独启用来满足特定的使用需要。
Kerberos 简介
Kerberos 是 Hadoop 生态广泛支持的一种用户认证协议。在未开启 Kerberos 认证时,Hadoop 的 文件系统客户端无法验证当前访问用户的真实性,可以简单通过 HADOOP_USER_NAME
环境变量设置用户访问的用户名,甚至可以是 superuser, 这会带来一定的安全问题。可以参考 Hadoop in Secure Mode 启用 Kerberos,如此一来,访问文件系统的用户就必须是通过 Kerberos 协议认证的,保证了真实性。
Kerberos 旨在通过使用密钥加密技术为 Client/Server 应用程序提供强身份验证。互联网是不安全的,如果密码通过网络传输,很容易被劫取。因此可以通过 Kerberos 协议实现一个安全的单点登录服务(SSO),整个过程密码均没有通过网络传输。
用下图大概介绍一下认证流程,图中 KDC 即为 Kerberos 的核心组件 Key Distribution Center:
Client 和 Server 均是 KDC 里的一个用户(Principal),需要提前在 KDC 里面添加。
大概流程:
- Client 通过自己的 Principal 和 keytab(password)登录 KDC 里面的 AS,AS 会返回一张临时票据(TGT),此 TGT 会有过期信息;
- Client 通过上一步获得的临时票据(TGT)向 KDC 的 TGS 请求需要访问的 Server Principal 的临时票据(ST);
- Client 通过上一部获得的临时票据(ST)向 Server 发起请求。Server 端使用自己的 keytab 可以验证 Client Principal 发来的请求。
整个过程只有第一步涉及到用户密码。但其实密码并没有通过网络发送:AS 返回的 TGT 里含有加密内容,只有当 Client 顺利解密,才视为登录成功。TGS 和 Server 会根据 Client 端从 KDC 获得的 TGT 和 ST 验证 Client 的真实性,同时,Server 端并不需要和 KDC 直接通信。
JuiceFS 中的 Kerberos
相比于直接信任 Client 输入的用户名,当 JuiceFS 元数据服务打开 Kerberos 认证后,Client 在访问元数据服务前需要先通过 Kerberos 认证。JuiceFS Client 和元数据服务各自有其 Principal 对应的 keytab 文件。
流程如下:
- 客户端通过
kinit
或者 keytab 文件从 KDC 获得 TGT,然后在用此 TGT 向 KDC 申请需要访问的 JuiceFS 元数据服务 principal 对应的 ST; - 客户端通过 ST 向 JuiceFS 元数据服务发起验证请求,JuiceFS 元数据服务根据自己的 principal 对应的 keytab 即可验证客户端的身份。
从上图可以看到,JuiceFS 的 Kerberos 身份认证只涉及 Client 和元数据服务之间的认证。Client 和对象存储之间不涉及 Kerberos 身份认证。
在通过 Kerberos 认证的过程中,TGT 是可以缓存在本地的,但是用来通过元数据服务认证的 ST 却无法缓存,也就是 client 每次初始化都需要向 KDC 发起请求。
在 YARN 任务中,通常会同时启动大量的进程访问 JuiceFS。如果每个 Client 都需要向 KDC 请求对应 JuiceFS 元数据服务的 ST,将会给 KDC 带来极大压力。为了解决这个问题,JuiceFS 参考 Hadoop Delegation Token 实现了 DelegationToken 验证。
DelegationToken 流程如下:
- Submit client 首先需要通过 Kerberos 认证和 JuiceFS 元数据服务建立连接;
- 建立连接后,计算框架(MR、Spark 等)会调用
FileSystem.getDelegationToken()
方法从 JuiceFS 元数据服务申请 DelegationToken; - 计算框架会把 DelegationToken 一并发送到 YARN ResourceManager,ResourceManager 会负责这些 token 的生命周期管理(如 renew、cancel);
- 具体任务节点启动后,YARN ResourceManager 会把 DelegationToken 发送给 task client; Task client 通过 DelegationToken 进行身份认证。
DelegationToken 是临时的,ResourceManager 会维护 ApplicationId 和其对应的 DelegationToken 并定期更新。DelegationToken 生命周期管理由 org.apache.Hadoop.yarn.server.resourcemanager.security.DelegationTokenRenewer
负责。
每个 token 都会有一个最大生命周期(maxDate),默认 7 天。如果程序运行时间大于 7 天,需要设置参数 yarn.resourcemanager.proxy-user-privileges.enabled=true
,这样在到期前,DelegationTokenRenewer 会通过代理用户机制重新为任务用户重新申请一个新的 DelegationToken。
开启 Kerberos 支持
JuiceFS>=4.8 的 Hadoop SDK 支持使用 Kerberos 做用户认证。
-
准备工作
-
如果没有安装 Kerberos,需要先安装 KDC
-
为 JuiceFS 创建
meta.keytab
文件,将VOL_NAME
需要替换为创建的 JuiceFS 文件系统名:kadmin.local -q "addprinc -randkey meta/{VOL_NAME}"
kadmin.local -q "ktadd -norandkey -k meta.keytab meta/{VOL_NAME}"
-
-
在 JuiceFS 控制台开启 Kerberos 支持
-
在文件系统的设置页面打开 Kerberos 支持,并上传之前步骤创建的 meta.keytab 文件
-
Superuser 和 Supergroup
当开启 Kerberos 支持后,superuser 和 supergroup 可以通过控制台设置。当设置后,控制台的值将会覆盖客 户端
juicefs.superuser
和juicefs.supergroup
设置的参数。 -
可选:代理用户
JuiceFS 也支持代理用户功能,请参考 HDFS Proxy User。当需要使用代理用户功能时,请添加代理用户规则。
-
-
SDK 客户端配置
修改
core-site.xml
,添加如下配置<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>juicefs.server-principal</name>
<value>meta/_HOST</value>
<description>
如果使用 _HOST 通配符,会被动态替换为访问的 JuiceFS 文件系统的名字,
也可以使用 meta/{VOL_NAME}, 指定具体的文件系统
</description>
</property> -
验证使用
-
Hadoop shell
# 通过 kinit 登录
kinit {your-client-principal}
# 验证 JuiceFS 正常运行
hadoop fs -ls jfs://{VOL_NAME}/
# 退出
kdestroy
# 退出以后,访问文件会报错:kerberos credential is needed
hadoop fs -ls jfs://{VOL_NAME}/ -
Spark
Spark 提交任务需增加以下配置:
--conf spark.yarn.access.hadoopFileSystems
-
客户端默认使用 /etc/krb5.conf
配置文件访问 KDC,如果 KDC 配置默认不在此位置,可以在 Java 启动参数里面添加 -Djava.security.krb5.conf=/path/to/conf
修改。