Hadoop KMS 透明加密配置以及测试

来源:互联网 发布:主板稳定性测试软件 编辑:程序博客网 时间:2024/06/10 21:03

转载来自: http://blog.csdn.net/linlinv3/article/details/44963429

http://blog.csdn.net/yunduanyou/article/details/76461223

背景介绍
    越来越多的用户关注安全问题,都在寻找一种有效的,方便的加密方式。hadoop提供了几种不同形式的加密,最底层的加密,加密所有节点数据,有效地保护了数据,但是却缺乏更细粒度的加密;
kms 透明加密可以做到更细粒度的加密;
    加密可以在不同的层级进行,包括软件/软件堆栈,选择不同的加密层级各有优缺点
  • 应用程序级加密。这是最安全、最灵活的方法。应用程序最终控制是什么加密,可以准确地反映用户的需求。然而,编写应用程序这样做是很难的。这也不是一个选择为客户现有的应用程序不支持加密。
  • 数据库级加密。类似的应用程序级加密的属性。大多数数据库厂商提供某种形式的加密。然而,可能有性能问题。一个例子是,索引不能加密。
  • 文件系统级进行加密。该选项提供了高性能、应用程序透明,通常容易部署。但是,它无法模型应用程序级别的一些政策。例如,多租户应用程序基于最终用户可能想要加密。一个数据库可能需要不同的加密设置每一列存储在单个文件中。
  • 磁盘级别加密。容易部署和高性能,但也很不灵活。
  hdfs处于数据库加密层和文件系统加密层之间。能有效地防止对文件系统的攻击,因为他的存储都是加密的。对于每个用户可以有不同的加密区

体系结构  

    Kms 有一个加密区 这个特殊的区域 对于能够进行操作他的用户 提供有写入和读取的权限。当加密区被创建的时候,每个加密区有唯一的秘钥, data encryption key (DEK),秘钥dek不由hdfs直接控制,但是hdfs控制encrypted data encryption key (EDEK),被加密的秘钥;由客户端解密EDEK;
    kms server  kms 服务器
    kms client    kms 客户端
    kms zone    kms 加密区

简单使用场景:

前提场景: 
人物:管理员s、用户a、用户b、外部无权人c 
管理员在hdfs上创建了一个目录A,让a来存取文件,而b无权查看(通过hdfs权限控制,和Linux上的文件权限控制一样) 
管理员在hdfs上创建了一个目录B,让b来存取文件,而A无权查看 
没有透明加密的时候: 
正常情况下,通过hdfs客户端,a只能查看A里的文件;b只能查看B的文件。 
但a(或者c)如果通过某种方式,进入hdfs的数据块存储区域,直接把B文件的数据块取出来,那么B文件就泄密了 
有透明加密的时候: 
管理员用密钥1把A目录设为“加密区”,用密钥2把B目录也设为“加密区” 
当a获取了B文件的数据块,由于他他没有A文件的使用权限,kms不会返回给他密钥2。 
当c获取了B文件的数据块,由于他也没有A文件的使用权,kms也不会返回给他密钥2。 
此时就保证了文件B的安全。

注:加密的是数据块,就是存在磁盘上的东西,在hdfs上直接看是自动解密了,加密的要直接取数据块看。

1.    环境准备:hadoo-2.6.5集群:主节点:slave3,从节点:slave4slave5.

2.    配置KMS:由于kms是跟hadoop结合在一起的,故可以直接到hadoop安装目录下的etc/hadoop去配置kms的配置文件,kms-siter.xml,kms-env.sh,kms-acls.xml


One ------kms server配置

(1)配置kms-site.xml:

kms backed keyProviderkeyProvider 存储地方的配置

Configure the KMS backingKeyProvider properties in the etc/hadoop/kms-site.xml configuration file:

配置kms keyProvider存储的地方

<!-- KMS Backend KeyProvider-->

 <property>

   <name>hadoop.kms.key.provider.uri</name>

   <value>jceks://file@/${user.home}/kms.keystore</value>

    <description>

      URI of the backing KeyProvider for theKMS.

    </description>

 </property>

 <property>

   <name>hadoop.security.keystore.JavaKeyStoreProvider.password</name>

   <value>kms.keystore</value>

    <description>

      If using the JavaKeyStoreProvider, thepassword for the keystore file.

    </description>

 </property>

 

这里的keystore需要用 java 秘钥生成器来生成

keytool -genkey  -alias 'key1';

keytool-delete  -alias 'key1';

注:有两个密码需要设定,这里我都设置为了123456,首先输入第一个密码,其他的随意写,直到出现no的时候写yes,然后输入第二个密码。

注:密码默认位置是在你的家目录下,默认名为.keystore,为隐藏文件,建议使用默认的方式创建密钥。

注:其他方式创建密钥:(指定kms密钥文件名和位置)

    keytool-genkey -alias 'kmskey' -keystore /kms.jks -dname "CN=localhost,OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass 123456 -storepass123456 -validity 180

注: 生成了keystore后,这个keystore就可以作为kms的密钥存储数据库了,由于这个keystore有访问密码(比如上面所设置的storepass :123456),这个密码是要告诉kms的,否则kms访问不了这个keystore,kms通过读取一个文本文件来获取密码。所以我们需要创建一个文本文件,在里面写上keystore访问密码。

<name>hadoop.security.keystore.JavaKeyStoreProvider.password</name>

    <value>kms.keystore</value>

这是指定文件名,文件创建位置和内容如下:


(2). kmscache kms 缓存配置:(默认就行无需修改)

The cache is used with thefollowing 3 methods only, getCurrentKey() and getKeyVersion() andgetMetadata().

配置缓冲区,这样的话,当获取  getCurrentKey() and getKeyVersion() andgetMetadata() 的时候 不用每次去访问 keystore 只用从缓存中读取就可以。当然,秘钥更新或者被删除的时候,会自动更新。

 <!-- KMS Cache -->

 <property>

   <name>hadoop.kms.cache.enable</name>

    <value>true</value>

    <description>

      Whether the KMS will act as a cache forthe backing KeyProvider.

      When the cache is enabled, operationslike getKeyVersion, getMetadata,

      and getCurrentKey will sometimes returncached data without consulting

      the backing KeyProvider. Cached valuesare flushed when keys are deleted

      or modified.

    </description>

 </property>

 

 <property>

   <name>hadoop.kms.cache.timeout.ms</name>

   <value>600000</value>

    <description>

      Expiry time for the KMS key version andkey metadata cache, in

      milliseconds. This affects getKeyVersionand getMetadata.

    </description>

 </property>

 

 <property>

   <name>hadoop.kms.current.key.cache.timeout.ms</name>

    <value>30000</value>

    <description>

      Expiry time for the KMS current keycache, in milliseconds. This

      affects getCurrentKey operations.

    </description>

 </property>

(3)、kmsaudit log 消息聚合日志配置

Audit logs are aggregated for APIaccesses to the GET_KEY_VERSION, GET_CURRENT_KEY, DECRYPT_EEK, GENERATE_EEKoperations.

 Entries are grouped by the(user,key,operation) combined key for a configurable aggregation interval afterwhich the number of accesses to the specified end-point by the user for a givenkey is flushed to the audit log.

配置聚合日志,将会对 (user,key,operation) 一样的操作进行合并输出,减少日志流量

<!-- KMS Audit -->

 <property>

   <name>hadoop.kms.audit.aggregation.window.ms</name>

    <value>10000</value>

    <description>

      Duplicate audit log events within theaggregation window (specified in

      ms) are quashed to reduce log traffic. Asingle message for aggregated

      events is printed at the end of thewindow, along with a count of the

      number of aggregated eventsfu.

    </description>

 </property>

(4)、kmssecurity kms 安全配置 (simple就可以满足需求)

这里可以有两种配置 一种是使用simple 一种是使用 kerberos

使用 simple 只用如下配置就可以

 <!-- KMS Security -->

 

 <property>

   <name>hadoop.kms.authentication.type</name>

    <value>simple</value>

    <description>

      Authentication type for the KMS. Can beeither &quot;simple&quot;

      or &quot;kerberos&quot;.

    </description>

 </property>

 

(5). kms-env.sh配置

KMS_HTTP_PORT

KMS_ADMIN_PORT

KMS_LOG

 export KMS_LOG=${KMS_HOME}/logs/kms

 export KMS_HTTP_PORT=16000

 export KMS_ADMIN_PORT=16001

配置完成后

启动 kms  sbin/kms.sh start ;

停止 ksm  sbin/kms.sh stop ;

jps 后发现进程有  Bootstrap 这个进程就说明启动成功;

 

(6).kms-acls.xml配置:(限制访问用户)

<property>

   <name>hadoop.kms.acl.DECRYPT_EEK</name>

    <value>wkz</value>(将*改为wkz用户,也就是hadoop的超级用户)

    <description>

      ACL for decryptEncryptedKeyCryptoExtension operations.

    </description>

  </property>

 

Two------kms客户端配置

(1)    hdfs-site.xml:添加如下

<property>

   <name>dfs.encryption.key.provider.uri</name>

   <value>kms://http@localhost:16000/kms</value>

</property>

(2)    core-site.xml:添加如下:

   <property>

     <name>hadoop.security.key.provider.path</name>

     <value>kms://http@localhost:16000/kms</value>

</property>

 

注:以上kms服务端和客户端所有配置均在主节点slave3进行的

注:kms客户端配置中localhost可以修改为slave3.

3.    完成以上所有配置后重启hadoop,同时注意以后修改kms后,只需重启kms.sh,即执行kms.shstop; kms.sh start

4.    创建key:

hadoopkey create key1   

hadoopkey list -metadata

 

5.    创建加密区(加密区必须是空目录,几级目录都行,但必须为空)

hdfs dfs -mkdir /jiami

hdfs crypto -createZone -keyName key1 -path /jiami

hdfs crypto -listZones



6.    测试

(1)    Hdfs上传下载查看:

用wkz用户在加密区/jiami下上传下载查看文件:

文件test内容如下:


测试如下:上传和下载


查看



测试发现一切正常。

再用test用户尝试:

test用户添加方法:首先开启linux acl权限(centos7默认开启),然后添加用户test:useradd test,设置密码:passwd test,

然后设置test用户对wkz用户jdk和hadoop的权限(使用wkz用户操作即可,hadoopacl没尝试,应该也行):setfacl -Rm u:test:rwx jdk1.7.0_80/(递归增加权限rwx);setfacl -Rm u:test:rwx hadoop。

之后再在test用户下设置环境变量如下:



测试文件helloWorld:


上传下载查看:


如设置一样,test用户没有权限去查看加密区内容,也没有权限上传下载。

注:如果把加密区设置权限为775(只要能让test用户有w权限就行),则上传报错为:


 

(2)    数据块查看:

在slave4和slave5上查找数据块:

发现在slave5上存在数据:


查看数据:


发现数据已经被加密。

测试非加密区数据查看情况:


发现数据在slave4上:


经查看数据未被加密。

(3)    其他客户端测试

slave5:不配置kms地址:

core-site.xml:

<configuration>

<property>

<name>fs.defaultFS</name>

<value>hdfs://slave3:9000</value>

</property>

<property>

<name>hadoop.tmp.dir</name>

<value>/home/wkz/hadoopdata</value>

</property>

<!--

<property>

     <name>hadoop.security.key.provider.path</name>

     <value>kms://http@slave3:16000/kms</value>

</property>

 -->

</configuration>

 

hdfs-site.xml:

<configuration>

<property>

<name>dfs.replication</name>

<value>1</value>

</property>

<!--

<property>

    <name>dfs.encryption.key.provider.uri</name>

    <value>kms://http@slave3:16000/kms</value>

</property>

-->

</configuration>

slave4:配置kms地址:

core-site.xml:

<configuration>

<property>

<name>fs.defaultFS</name>

<value>hdfs://slave3:9000</value>

</property>

<property>

<name>hadoop.tmp.dir</name>

<value>/home/wkz/hadoopdata</value>

</property>

<property>

     <name>hadoop.security.key.provider.path</name>

      <value>kms://http@slave3:16000/kms</value>

</property>

</configuration>

hdfs-site.xml:

<configuration>

<property>

<name>dfs.replication</name>

<value>1</value>

</property>

<property>

    <name>dfs.encryption.key.provider.uri</name>

    <value>kms://http@slave3:16000/kms</value>

</property>

</configuration>

配置完,重启hadoop

查看:

slave5无法查看:


slave4可以查看:

自此所有测试完毕,hdfs数据加密实现.


ps:后来发现一种更好的查看hdfs文件在linux上的具体存储信息的方式,就是我们不需要再去找block块去查看数据了,具体如下:

hdfs dfs -ls /.reserved/raw  (我们可以看到hdfs跟目录下的所有文件及文件夹)


然后我们查看加密空间/jiami内的数据:

hdfs dfs -cat /.reserved/raw/jiami/test


发现查到的确实是存在磁盘上文件原始内容,即被加密后的内容。


原创粉丝点击