如何在 Hadoop mapReduce 中获取 Kerberos 而不是委托令牌?

Posted

技术标签:

【中文标题】如何在 Hadoop mapReduce 中获取 Kerberos 而不是委托令牌?【英文标题】:How to get Kerberos instead of delegation token in Hadoop mapReduce? 【发布时间】:2012-07-25 18:47:45 【问题描述】:

我是 Java 用户,在向 Hadoop mapReduce 提交作业时,它使用 Kerberos 对 Hadoop 进行身份验证,成功后会创建委托令牌并将其与作业提交一起传递给 Hadoop,而不是 kerberos 票证(出于安全考虑原因如 Hadoop 所述)。现在作业以我的身份运行,但作业本身需要使用 Kerberos 向 Hadoop 之外的其他服务发送请求。现在我在 Hadoop 上没有 kerberos TGT,我无法获得服务票证。

无论如何我可以通过 Kerberos 票证与工作吗? (我知道这可能很危险,因为我们不想传递秘密),JobConf 可以将字符串到字符串对传递给 Hadoop,但我必须将 TGT 转换为 json 字符串并在作业运行期间将其还原?

或者是否可以使用委托代币改革TGT?

我用谷歌搜索,但信息不多,有人可以帮忙吗?谢谢。

**已编辑:**

如果不将 TGT 传递给 Hadoop,似乎没有简单的方法可以做到这一点,所以我将尝试以下方法,通过作业配置映射将 TGT 作为字符串传递给 Hadoop(仅限字符串),然后将字符串转换回当作业在 Hadoop 中运行时到 TGT 对象。担心的是我将通过网络传递凭据,这不是最佳实践,也是 Hadoop 没有传递 Kerberos 以确保安全的原因之一。如果我可以重新使用传递给 Hadoop 的改造后的 TGT 来获取服务票证,我会尽量加密 TGT 字符串以避免安全问题。

所以在本地机器上开始工作之前,代码应该是这样的:

import sun.security.krb5.Credentials;  

Credentials tgt = Credentials.acquireTGTFromCache(null, null); // Make sure kinit is done before this

String tgtStr = tgt.convertToJsonString(); //Need to implement this

Job job = new Job("Test");
JobConf jobConf = job.getJobConf();
jobConf.set("tgtStr", tgtStr);
job.addTask(Test.class, "run", null);
job.submit();
job.waitForCompletion(true);

那么 Hadoop 运行的作业中的函数将是:

Configuration conf = TaskContext.get().getConfiguration();
String tgtStr = conf.get("tgtStr");
Credentials tgt = reformTGTFromString(tgtStr);//Need to implement this
Credentials serviceTicket = Credentials.acquireServiceCreds(servicePrincipal, tgt); //This is to get any service ticket

所以我需要实现两个函数将 TGT 对象(Credentials.class)流式传输到字符串,然后将其重新转换回对象。

有人知道更好的解决方案吗?谢谢。

【问题讨论】:

通过分解Credentials字段并使用Base64编码器将它们转换为Strings,形成JSON字符串并使用配置映射或RVM建议的分布式缓存将其传递给Hadoop,然后在作业中重构Credentials对象在 Hadoop 上运行,我可以取回 Kerberos TGT 并使用它成功获取任何服务票证。所以这个方法是有效的,这里唯一需要非常小心的是对通过网络传递的密钥进行加密。 我知道这已经很老了,但是 Java 8 现在支持约束委派 (S4U);可以只将服务票证传递给 Hadoop,然后使用适当配置的帐户请求票证到特定服务。 Java 8 - S4U 【参考方案1】:

如果您还没有这样做,请参阅http://carfield.com.hk:8080/document/distributed/hadoop-security-design.pdf 的设计。

或者可以使用委托代币改革TGT吗? 不,委托令牌由 Hadoop 名称节点颁发,虽然它基于 Kerberos 身份验证,但它是独立的,您不能从中派生 Kerberos TGT。

在最初的设计中,我们考虑过仅使用 Kerberos(没有任何额外的令牌),这会使您的计划变得容易,但出于以下原因决定放弃:

性能:

数以千计的 M/R 任务可能需要在 同一时间 Kerberos 凭据需要在到期前更新 对于预定的作业,这将是一个问题 委托令牌不依赖于 Kerberos,可以与边缘使用的非 Kerberos 身份验证机制(例如 SSL)结合使用。

在您的情况下,您可以使用私有分布式缓存并发送可转发的 TGT。我认为这没问题,但需要再考虑一下。显然,您需要确保您的实施是安全的,您的票证具有最低限度的必要生命周期,如果可能的话,使用 IP 通道绑定,并将票证的使用仅限于授权流程。

【讨论】:

感谢您的建议,我的计划是以安全的方式(希望)将 TGT 传递给 Hadoop 以测试它是否有效。我已经编辑了帖子,提供了有关实施的更多细节,还有更多见解吗?谢谢。 您应该考虑使用分布式缓存 hadoop.apache.org/common/docs/r0.20.2/api/org/apache/hadoop/… 而不是将 tgt 放在作业 conf 中。这样会更安全。我不记得jobconf的访问权限是什么。即便如此,也可能会记录作业配置属性。所以分布式缓存可能比jobconf更安全。【参考方案2】:

通过分解 Credentials 字段并使用 Base64 编码器将其转换为字符串,形成 JSON 字符串并使用 RVM 建议的配置映射或分布式缓存将其传递给 Hadoop,然后在 Hadoop 上运行的作业中重构 Credentials 对象,我可以取回 Kerberos TGT 并使用它成功获取任何服务票证。所以这个方法是可行的,这里唯一需要非常小心的是对通过网络传递的密钥进行加密。

【讨论】:

【参考方案3】:

首先,您的帐户必须启用委派。服务票证必须请求可转发票证。如果这一切都是真的,Hadoop 必须从 GSSContext 检索委托凭证并代表您构建一个新凭证。有了这个新的 TGT,它将能够执行进一步的步骤。使用 Wireshark 检查 hadoop 的票证。

【讨论】:

谢谢你的解释,所以为了从委托服务票证构造新的凭证,GSSContext需要原始票证,对吗?如何将本地获取的服务票证传递给 Hadoop?如我错了请纠正我。谢谢。 我对 Hadoop 没有经验,但您必须检查 Hadoop 是否可以访问 GSSContext 并将凭据保存在某处。这就是它的方式。 This 是它的工作原理。

以上是关于如何在 Hadoop mapReduce 中获取 Kerberos 而不是委托令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取hadoop mapreduce job运行信息

如何记录hadoop mapreduce运行日志

请教如何在hadoop获取数据

如何获取Hadoop Native Lib

如何获取Hadoop Native Lib

Hadoop ---- MapReduce