该文档讲述hadoop的kms组件的概念以及使用
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是一个密钥管理服务器,它并不负责加密文件
HDFS 实现透明,端到端加密。配置完kms后,用户往hdfs上存储数据的时候,无需用户做任何程序代码的更改(意思就是调用KeyProvider API ,用于在数据存入到HDFS上面的时候进行数据加密,解密的过程一样)。这意味着数据加密和解密由客户端完成的。
前提场景:
人物:管理员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的安全。
Kms和Hdfs配合使用的作用旨在补全hdfs权限管控的安全漏洞,正常使用hdfs时,用户感觉不到文件加密的存在,所以叫“hdfs透明加密”。
kms是hadoop自带的组件,只要安装了hadoop,kms相关的东西就都有了,只要简单配置 并启动就可以使用了
使用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必须使用的自己产生的密钥,这一步的意义仅仅是产生一个密钥容器)
生成了keystore后,这个keystore就可以作为kms的密钥存储数据库了,由于这个keystore有访问密码(比如上面所设置的storepass :123456),这个密码是要告诉kms的,否则kms访问不了这个keystore,kms通过读取一个文本文件来获取密码。 所以我们需要创建一文本文件,在里面写上keystore访问密码
下面讲怎么把 keystore 和 这个keystore的访问密码配置到kms配置文件中,让kms读取
kms由于是hadoop自带的组件,所以kms的配置文件默认和hadoop放在一起
配置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.jks:意义:keystore地址:这个地址前面的jceks://file@是固定写法不要随意改变或删除,kms在获取了这个地址之后会把他转换为file:// {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中(放在其他目录系统会找不到而报错)
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地址
<property>
<name>dfs.encryption.key.provider.uriname>
<value>kms://http@localhost:16000/kmsvalue>
property>
<property>
<name>hadoop.security.key.provider.pathname>
<value>kms://http@localhost:16000/kmsvalue>
property>
配置完上面这两个后,需要重启hadoop
进入hadoop安装目录
命令:sbin/.kms.sh start
命令:sbin/.kms.sh stop
jps————>找到进程Bootstrap
kill -9 Bootstrap的Pid
命令:sbin/.kms.sh stop
jps————>找到进程Bootstrap
kill -9 Bootstrap的Pid
rm -rf /tmp/kms.pid
…..(做某些更改:重启往往都是为了改某些配置什么的)…
sbin/.kms.sh start
当执行完sbin/.kms.sh start后
执行jps查看kms的进程Bootstrap是否启动
打开 hadoop的log/kms目录(前面配置的时候 把kms的日志配置到这里了)
vim kms.catalina.out 查看是否有报错(前面的keystore和密码文件位置的配置有问题时,启动就会报错)
为什么执行完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自己使用的密钥,有自己的使用机制
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]]
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
roll <keyname> [-provider <provider>] [-help]:
The roll subcommand creates a new version for the specified key
within the provider indicated using the -provider argument
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的密钥就被删除了
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 列出所有密钥(包含密钥的其他信息属性)
使用hdfs crypto
命令来操作加密区,之后 被放入加密区的文件会被自动加密,有权限查看的用户 查看 会自动解密
hdfs crypto -createZone -keyName testkey1 -path /somepath
testkey1 :密钥名
/sompath : 需要被设置为加密区的目录
hdfs crypto -listZones