文档章节

也说Hadoop敏感信息加密方案的尝试(下)

问津已非少年
 问津已非少年
发布于 2016/12/18 22:55
字数 2535
阅读 298
收藏 1

前面讲到了AES对称加密的两个不同方案,一是Hive表存储秘钥,一是用KMS来存储秘钥。在这两个大的分类下,又各自有两种不同的方案,每种方案的尝试都是因为踩到了坑,所以才不得不换一种姿势。

前文博客见 也说Hadoop敏感信息加密方式的尝试(上)

#KMS秘钥存储方案 关于KMS的讲解和配置,可见博文 KMS秘钥管理服务(Hadoop)。这里只讲其在加密方案中的应用。

##方案一:直接从KMS获取秘钥 这里利用KMS存储字段加密秘钥,在每个Hive或Spark任务提交到集群的时候,集群都会进行提交者的Kerberos身份认证,我们就在Hive/Spark UDF里利用当前Kerberos身份来获取秘钥。

看起来好像很顺理成章,事实证明 测试环境 下,在Spark UDF里确实可以顺利利用提交账户获取到该账户所能获取到的秘钥,进行字段加解密。但是我们发现在Hive里,这种方案行不通,观察KMS的审计日志发现,所有在beeswaxbeeline里使用UDF提交的查询,向KMS请求秘钥的用户身份都是hive。也就是说Hive里的代理用户身份设置并没有生效,用户向Hive提交的任务,Hive最后还是以hive的身份鉴权和执行!

这里的情况让我有点惊愕,因为我们提交的所有hive任务,其实都是经过了鉴权的,不可能是以hive身份来鉴权。所以意识到是我们在哪弄错了,因为集群上了Sentry,它提供了不止基于UNIX文件系统的鉴权,所以集群上的HiveServer2是与Sentry结合的。所有经过HiveServer2的任务都要先经过Sentry的鉴权,鉴权通过Hive才会往下执行。

而在安装Sentry的时候,是明确要求Hive关闭impersonation的,也即hive.server2.enable.doAs = false,这个功能就是Hive的代理用户功能,关掉它之后,所有提交给Hive的任务都将以hive的身份执行!所以成也Sentry败也Sentry,我们在Hive UDF里拿到的当前认证用户就是hive,拿不到实际提交用户的Kerberos认证!

由于在Hive UDF里拿不到提交用户的Kerberos认证,所以这一方案就被KO了

##方案二:通过MapredContext获取提交用户名 这是对上一个方案的延伸,由于在Hive UDF里拿不到当前提交用户的Kerberos认证,所以只能绕一下。在GenericUDF里有个函数 public void configure(MapredContext context) ,通过传入的context,我们可以用context.getConf()来拿到Map函数的Configuration,然后通过hive.sentry.subject.name配置,拿到提交的真正账户名。

在GenericUDF里,如果configure函数执行的话,它在initialize函数之前执行。通过从configure函数里拿到真正提交账户,我们在initialize函数里向KMS取秘钥就可以利用真正提交账户构造Kerberos认证。

但是configure函数的执行是有条件的,只有Hive的底层引擎是MapReduce时,这个函数才有可能执行,否则它不会执行。所以底层引擎不是它的时候,这种方式是行不通的。

这种方案里我们将授权人员的keytab文件进行AES加密,放入jar包里,将keytab秘钥存于KMS,在Hive UDF里先以hive身份请求keytab文件秘钥,然后解密当前提交账户的keytab。之后利用从configure函数里拿到的提交用户的身份去访问KMS,获取该用户权限范围内的字段秘钥。

方案在这里看起来似乎也是很OK的,在测试环境里,很OK的通过了。然后到线上后,发现出了BUG!无论是Spark还是Hive,都只有部分 能进行加解密成功,从日志上看只加解密了一部分数据就开始报错,报Kerberos认证失败

失败了,那就开始查日志吧,从日志上发现,所有Spark认证失败的都是位于其他节点机上的,而位于提交任务的节点机上的executor则没有失败。在Hive上也一样,位于当前提交任务的节点机上的task是成功的,其他节点机上的是失败的。为什么其他节点机上的任务就会认证失败呢?

其实是因为其他节点机上并没有提交用户的tgt缓存(kinit得到的),无论Spark还是Hive,在启动任务的时候,都会拿到HDFSDelegationToken, YarnDelegationToken等经过Kerberos认证后的token,所有的task上都会带上这些token,而不会带上提交节点机上的Kerberos UGI信息。task之后通过token来做权限验证,在token失效时间之内,用token来做验证就不需要再请求KDC来做认证,直接由token就可以认证当前用户是否有权限执行相关操作!而在用户提交的节点机上,cache里有当前用户的tgt,在上面跑的task通过UGI认证时,可以直接拿到tgt来认证,自然可以认证通过。而其他节点机上并没有提交用户的tgt,认证通过不了,任务自然失败。

上面的问题之所以在测试环境未曾出现,是因为测试环境只有唯一一台节点机上没有测试账户的tgt,而测试的时候,所有的任务刚好都没有分到那台机器上,或者分配到上面没执行成功,任务重试时分配在其他机器上成功了,从而没被我注意到。

方案走到这一步,又走到绝路了。除非在Hive和Spark提交任务时,像HDFSDelegationToken一样,先获取到当前用户或hive用户KMS认证后的DelegationToken,然后以插件的形式注册到任务提交代码里,从而分发到执行节点task上去,由执行节点通过token来做KMS认证。但是这一步不说能不能做成,就单做起来就很麻烦,还可能需要改源码,需要花太大精力,不然官方早就有了完善的加密方案!

或者很猥琐的在集群各节点机上布置需要加解密服务的用户的tgt,让节点上的任务在执行时可以拿到认证信息。但是这样做不是正路子也不方便。

所以方案到这就被掐死了,包括凡是想利用Kerberos认证的方案,到这都走不通!

#Hive表秘钥存储方案 Hive表存储秘钥理解起来就比较简单,但是实践起来也可以分两种方案。一种对外透明,一种需要用户传key,相对猥琐一点。但是实践证明,猥琐的反而好使!

##方案一:在Hive UDF里获取Hive秘钥表的加密key 这种方案属于对外透明型的,用户只需传入加密字段类型和加密字段,就可以完成数据加密,不需要去管秘钥的存储。

但在测试环境验证从Hive UDF取Hive表数据的时候,发现JDBC取Hive表数据在拿到Connection,开始执行SQL语句的时候卡住了,多次尝试一直卡在那,而后台HiveServer2的日志也在get Session后不动。这个问题查了好几次,没查到到底为什么,猜测是在Hive UDF里实际是以hive用户去取Hive表的数据,可能会出现问题,但是并没有查到到底为什么!考虑到在线上环境里,问题还是回到了Kerberos认证的问题,其他节点机上拿不到认证信息,连接HS2都会连不上!所以之后就没有再探索这个问题。

这一方案跟Kerberos认证相关,而且由于Hive UDF里取Hive表数据也存在问题,所以也被KO了

##方案二:UDF提供传入Key的参数,UDF只做加密,由用户传入key 这种方案是当时AES加密里最不看好的一种方案,因为由用户传入key有很大安全隐患,而且API显得特别矬。

但是由于Key存于HIve表,我们可以控制权限。在UDF里我们只做加密,而不做其他额外的操作,UDF本身简单了很多,不用考虑权限认证的问题。所以这是种最简单的方式,经验证也是最行之有效的方式!

就这样,林林总总选择又放弃了前面的五种方案(其实尝试的时候还不止,有些是细节上的变动,这里就没有记录),最后选了一种当初觉得最矬的方案~~ 真是不到最后不甘心啊!

#问题记录

  • 在Hive的Imperonation关闭之后,怎么才能在Hive UDF里拿到真实提交用户的Kerberos认证? 不只是获取提交用户的用户名,而希望拿到UGI。
  • 如何才能在MR的task里分发KMS认证后的DelegationToken?以怎样的形式注册到Hive和Spark的启动程序里,像HDFS和Yarn一样?
  • 在集群上了Sentry的环境下,Hive UDF里获取Hive表无法拿到数据的原因?语句不执行的原因?

如果前两个问题能有效的解决掉,我想一套正式不猥琐的加密方案就可以面世了。加油!加油!

小主们转载请注明出处:https://my.oschina.net/u/2539801/blog/808061

© 著作权归作者所有

问津已非少年
粉丝 19
博文 21
码字总数 33944
作品 0
海淀
程序员
私信 提问
保障 Hadoop 数据安全的十大措施

Dataguise最近发布了Hadoop十大数据安全措施,内容涵盖隐私风险、数据管理和信息安全等,可以帮助专业人士降低大数据应用的潜在数据泄漏和政策违规等风险,对于那些考虑部署Hadoop的企业来说...

oschina
2013/04/08
2.6K
5
Hadoop专业解决方案-第12章 为Hadoop应用构建企业级的安全解决方案

一、前言:   非常感谢Hadoop专业解决方案群:313702010,兄弟们的大力支持,在此说一声辛苦了,春节期间,项目进度有所延迟,不过元宵节以后 大家已经步入正轨, 目前第12章 为Hadoop应用...

张子良
2014/02/18
253
0
Spring .properties配置文件加密

Spring .properties配置文件加密 OneCoder2017-04-1077 阅读 Spring 对于保存在.properties文件中的敏感信息,支持采用加密的方式保存。然后在程序中解密使用。 实现方案 采用自定义Propert...

OneCoder
2017/04/10
0
0
网站漏洞检测对漏洞检测修复方案

在网站安全的日常安全检测当中,我们SINE安全公司发现网站的逻辑漏洞占比也是很高的,前段时间某酒店网站被爆出存在高危的逻辑漏洞,该漏洞导致酒店的几亿客户的信息遭泄露,包括手机号,姓名...

网站安全
2018/12/14
0
0
网站安全公司对于网站逻辑漏洞的修复方案分享

在网站安全的日常安全检测当中,我们SINE安全公司发现网站的逻辑漏洞占比也是很高的,前段时间某酒店网站被爆出存在高危的逻辑漏洞,该漏洞导致酒店的几亿客户的信息遭泄露,包括手机号,姓名...

网站安全
2018/12/14
20
0

没有更多内容

加载失败,请刷新页面

加载更多

Java描述设计模式(14):解释器模式

本文源码:GitHub·点这里 || GitEE·点这里 一、解释器模式 1、基础概念 解释器模式是对象的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客...

知了一笑
5分钟前
1
0
019、Kubernetes 安装集群

概述 kubeadm 是 kubernetes 的集群安装工具,能够快速安装 kubernetes 集群,安装 kubernetes 主要是安装它的各个镜像,而 kubeadm 已经为我们集成好了运行 kubernetes 所需的基本镜像。但由...

北岩
20分钟前
3
0
Java每日面试题_02

13、Java中实现多态的机制是什么? Java中,靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方...

庭前云落
21分钟前
2
0
kafka 生成者,消费者 demo

写生成者和消费者 producer 生产者 public class ProducerDemo {public static void main(String[] args) throws Exception {Properties props = new Properties();props.put("zk......

Garphy
27分钟前
2
0
各版本JDK:JDK6;JDK7;JDK1.8;JDK11;JDK13

百度网盘 链接: https://pan.baidu.com/s/1S1W6XQOEj4m8uRQZ3rMbNA&shfl=shareset 提取码: 1jke jdk-13.0.1 jdk-11.0.5 jdk-8u231 华为镜像 链接: https://repo.huaweicloud.com/java/jdk/......

孑竹三秋
30分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部