Hadoop-kms总结

一.前言

该文档讲述hadoop的kms组件的概念以及使用

二.概念

1). 官方说明:

Hadoop KMS是一个基于 Hadoop的 KeyProvider API的用密码写的 key 管理server。Client是一个KeyProvider的实现,使用KMS HTTP REST API与KMS交互。
KMS和它的客户端内置安全和它们支持HTTP SPNEGO Kerberos 身份验证和HTTPS安全转换.
KMS是一个Java Web应用程序,运行在与Hadoop发行版绑定在一起的预先配置好的Tomcat服务器上。
注意:Kms是一个密钥管理服务器,它并不负责加密文件

2). 透明加密:

HDFS 实现透明,端到端加密。配置完kms后,用户往hdfs上存储数据的时候,无需用户做任何程序代码的更改(意思就是调用KeyProvider API ,用于在数据存入到HDFS上面的时候进行数据加密,解密的过程一样)。这意味着数据加密和解密由客户端完成的。

3). 透明加密过程:

  1. 用户向hdfs请求资源
  2. hdfs判断用户的权限(hdfs的文件权限控制)
  3. 如果用户有权限,如果文件没加密,则直接打开返回给用户。如果发现文件是加密的,则根据用户的权限和 资源向kms请求密钥。
  4. Kms判断用户的权限和资源,有权限,则返回相应的密钥。
  5. Hdfs拿到密钥将文件解密后返回给用户

4). 简单使用场景:

前提场景:
人物:管理员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的安全。

5). 一句话概括:

Kms和Hdfs配合使用的作用旨在补全hdfs权限管控的安全漏洞,正常使用hdfs时,用户感觉不到文件加密的存在,所以叫“hdfs透明加密”。

三.配置kms

kms是hadoop自带的组件,只要安装了hadoop,kms相关的东西就都有了,只要简单配置 并启动就可以使用了

1). 创建密钥数据库(keystore)

使用jdk的密钥生成器keytool来生成密钥
命令:keytool -genkey -alias ‘key1’;
说明:
keytool : 密钥生成器的命令
-genkey: 密钥生成器的生成密钥的参数
-alias: 密钥生成密钥时给密钥取别名时的参数、
‘key1’ : 我们给这个密钥取得别名(也就是密钥的名字,可以随便取)

回车之后,密钥生成器还需用户填入密码以及其他用户信息,按照要求填写完毕即可
按照这个流程执行完之后,密钥会在用户的系统目录里生成(Linux是:/home/用户名),直接打开该目录看不到新生成的文件,因为这是个隐藏文件(文件名默认为: .keystore)
使用ls -a即可看到该文件(keystore后缀可以是.keystore 或者 .jks)
还可以一次性把密钥生成器所需的全部参数一次性写完,包括定义keystore的文件名及存储路径,如:

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

keytool具体使用及说明详见keytool使用文档
说明一点:一个keystore中可以放多个密钥,只要多次生成密钥,并且保证指向的是同一个keystore(不过这里即使产生多个也没啥用,后面会讲hadoop必须使用的自己产生的密钥,这一步的意义仅仅是产生一个密钥容器)

2). 创建密码文件:

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

下面讲怎么把 keystore 和 这个keystore的访问密码配置到kms配置文件中,让kms读取
kms由于是hadoop自带的组件,所以kms的配置文件默认和hadoop放在一起

3). 配置kms-site.xml

配置kms keyProvider存储的地方,也就是密钥存储的地方


  <property>
    <name>hadoop.kms.key.provider.uriname>
    <value>jceks://file@/${user.home}/kms.jksvalue>
    <description>
      URI of the backing KeyProvider for the KMS.
    description>
  property>
  <property>
    <name>hadoop.security.keystore.java-keystore-provider.password-filename>
    <value>kms.passwdvalue>
    <description>
      If using the JavaKeyStoreProvider, the password for the keystore file.
    description>
  property>

说明:
的值是固定的写法,必须要这么写
hadoop.kms.key.provider.uri
jceks://file@/ user.home/kms.jkskeystorejceks://file@kmsfile:// {user.home}/kms.keystore来访问,如果用户是aa,那么kms就会找/home/aa/kms.jks这个文件

hadoop.security.keystore.java-keystore-provider.password-file
kms.keystore
意义:keystore的访问密码文件地址,也就是在生成keystore时,输入的-storepass
注意:这个地址的意思是“kms.passwd”这个文件要放在kms的tomcat下的classes中(放在其他目录系统会找不到而报错)

4). kms-ent.sh 配置

KMS_LOG

 export KMS_LOG=${KMS_HOME}/logs/kms

 export KMS_HTTP_PORT=16000

 export KMS_ADMIN_PORT=16001

上面算是kms的服务器所需要的配置,下面讲kms客户端所需要的配置。但kms是通过api对外提供服务的,所以kms的客户端就是它对外暴露的api地址

5). kms-site.xml 配置

<property>
     <name>dfs.encryption.key.provider.uriname>
     <value>kms://http@localhost:16000/kmsvalue>
property>

6). core-site.xml 配置

<property>
      <name>hadoop.security.key.provider.pathname>
      <value>kms://http@localhost:16000/kmsvalue>
property>

配置完上面这两个后,需要重启hadoop

7). 其他kms的配置详见kms的官方文档(大部分都是默认配好的,无需用户更改)

四.起停操作

进入hadoop安装目录

1). 启动

命令:sbin/.kms.sh start

2). 关闭

命令:sbin/.kms.sh stop
jps————>找到进程Bootstrap
kill -9 Bootstrap的Pid

3). 重启

命令:sbin/.kms.sh stop
jps————>找到进程Bootstrap
kill -9 Bootstrap的Pid
rm -rf /tmp/kms.pid
…..(做某些更改:重启往往都是为了改某些配置什么的)…
sbin/.kms.sh start

4). 查看运行状况

当执行完sbin/.kms.sh start后
执行jps查看kms的进程Bootstrap是否启动
打开 hadoop的log/kms目录(前面配置的时候 把kms的日志配置到这里了)
vim kms.catalina.out 查看是否有报错(前面的keystore和密码文件位置的配置有问题时,启动就会报错)

5). 说明

为什么执行完sbin/.kms.sh stop还需要杀掉Bootstrap进程?
因为sbin/.kms.sh stop只是关闭了tomcat进程,并没有关闭Bootstrap
为什么重启时需要删除/tmp/kms.pid?
这是tomcat频繁启动会出现的问题
!以上两个问题不是必现问题,就是说,出现了才这么做,正常情况下./kms stop就可以自动杀掉Bootstrap进程和删除kms.pid
还有:一开始使用keytool生成keystore时生成的密钥key.kms(准确的说应该是生成密钥时生成的keystore),是不能用于hadoop创建加密区的,因为这个密钥是正规的“密钥”,而hadoop自己使用的密钥,有自己的使用机制

五.API–shell

kms通过shell脚本命令hadoop命令来增删查密钥

命令:hadoop key xxxx

[root@bogon ~]# hadoop key -help
Usage: hadoop key [generic options]
   [-help]
   [create  [-cipher ] [-size ]
                     [-description ]
                     [-attr ]
                     [-provider ] [-help]]
   [roll  [-provider ] [-help]]
   [delete  [-provider ] [-f] [-help]]
   [list [-provider ] [-metadata] [-help]]

1).

create  [-cipher ] [-size ]
                     [-description ]
                     [-attr value>]
                     [-provider ] [-help]:

The create subcommand creates a new key for the name specified
by the  argument within the provider specified by the
-provider argument. You may specify a cipher with the -cipher
argument. The default cipher is currently "AES/CTR/NoPadding".
The default keysize is 128. You may specify the requested key
length using the -size argument. Arbitrary attribute=value
style attributes may be specified using the -attr argument.
-attr may be specified multiple times, once per attribute.

说明
这个命令用于创建hadoop密钥
cipher(加密算法)默认是AES/CTR/NoPadding
bitLength(密钥长度)默认是128位
可以添加description(描述信息)
attributes(其他属性,可以添加多个键值对)
简单使用:hadoop key create testkey1

2).

roll <keyname> [-provider <provider>] [-help]:

The roll subcommand creates a new version for the specified key
within the provider indicated using the -provider argument

3).

delete <keyname> [-provider ] [-f] [-help]:

The delete subcommand deletes all versions of the key
specified by the argument from within the
provider specified -provider. The command asks for
user confirmation unless -f is specified.
说明:用于删除密钥
简单使用:hadoop key testkey1 名字叫testkey1的密钥就被删除了

4).

list [-provider <provider>] [-metadata] [-help]:

The list subcommand displays the keynames contained within
a particular provider as configured in core-site.xml or
specified with the -provider argument. -metadata displays
the metadata.
说明:用户查看keystore中存储的密钥
简单使用:hadoop key list 列出所有密钥
hadoop key list -metadata 列出所有密钥(包含密钥的其他信息属性)

5). 创建加密区

使用hdfs crypto 命令来操作加密区,之后 被放入加密区的文件会被自动加密,有权限查看的用户 查看 会自动解密

hdfs  crypto -createZone  -keyName  testkey1  -path  /somepath

testkey1 :密钥名
/sompath : 需要被设置为加密区的目录

6). 查看加密区

hdfs  crypto -listZones

7). 注意

  1. 当密钥K已经被用于加密了某个hdfs文件夹,再删除这个密钥K,是可以删除成功的
  2. 当某个文件夹已经用密钥K1设置为加密区了,再用k2设置这个目录为加密区的时候,会报错,并创建加密区失败:
    RemoteException: Directory /testdir2 is already in an encryption zone. (/testdir2)
  3. 当某个目录里有其他目录,不能用于创建加密区
    RemoteException: Attempt to create an encryption zone for a non-empty directory.
  4. 成功创建加密区后:
    Added encryption zone /testdir2
  5. 所有密钥操作的前提是kms必须正常开启并可访问,否则会报错:
    Cannot list keys for KeyProvider: KMSClientProvider[http://192.168.50.157:16000/kms/v1/]: java.net.ConnectException: Connection refused
  6. 如果想换一个keystore,比如想把另一个系统个密钥迁移过来,直接拷贝keystore文件是不行的,因为kms有文件校验机制:在keystore的同级目录会有一个隐藏文件.keystore.crc,用于校验keystore的完整性,如果想从其他地方迁移一个keystore,必须先把本地这个.crc校验文件删除(不用担心:当做下一次keystore更新的时候,比如新增一个密钥,kms会自动检查并新增一个.crc文件)

你可能感兴趣的:(大数据)