Hadoop 2.10.1 HDFS 透明加密原理 + 实战 + 验证
一、背景介紹
-
越來越多的用戶關(guān)注安全問題,都在尋找一種有效的,方便的加密方式。hadoop提供了幾種不同形式的加密,最底層的加密,加密所有節(jié)點數(shù)據(jù),有效地保護了數(shù)據(jù),但是卻缺乏更細粒度的加密;
-
kms 透明加密可以做到更細粒度的加密;
加密可以在不同的層級進行,包括軟件/軟件堆棧,選擇不同的加密層級各有優(yōu)缺點- 應用程序級加密。這是最安全、最靈活的方法。應用程序最終控制是什么加密,可以準確地反映用戶的需求。然而,編寫應用程序這樣做是很難的。這也不是一個選擇為客戶現(xiàn)有的應用程序不支持加密。
- 數(shù)據(jù)庫級加密。類似的應用程序級加密的屬性。大多數(shù)數(shù)據(jù)庫廠商提供某種形式的加密。然而,可能有性能問題。一個例子是,索引不能加密。
- 文件系統(tǒng)級進行加密。該選項提供了高性能、應用程序透明,通常容易部署。但是,它無法模型應用程序級別的一些政策。例如,多租戶應用程序基于最終用戶可能想要加密。一個數(shù)據(jù)庫可能需要不同的加密設置每一列存儲在單個文件中。
- 磁盤級別加密。容易部署和高性能,但也很不靈活。
hdfs處于數(shù)據(jù)庫加密層和文件系統(tǒng)加密層之間。能有效地防止對文件系統(tǒng)的攻擊,因為他的存儲都是加密的。對于每個用戶可以有不同的加密區(qū)
-
體系結(jié)構(gòu)
- Kms 有一個加密區(qū) 這個特殊的區(qū)域 對于能夠進行操作他的用戶 提供有寫入和讀取的權(quán)限。當加密區(qū)被創(chuàng)建的時候,每個加密區(qū)有唯一的秘鑰, data encryption key (DEK), 秘鑰dek不由hdfs直接控制,但是hdfs控制 encrypted data encryption key (EDEK) ,被加密的秘鑰;由客戶端解密 EDEK;
kms server kms 服務器
kms client kms 客戶端
kms zone kms 加密區(qū)
- Kms 有一個加密區(qū) 這個特殊的區(qū)域 對于能夠進行操作他的用戶 提供有寫入和讀取的權(quán)限。當加密區(qū)被創(chuàng)建的時候,每個加密區(qū)有唯一的秘鑰, data encryption key (DEK), 秘鑰dek不由hdfs直接控制,但是hdfs控制 encrypted data encryption key (EDEK) ,被加密的秘鑰;由客戶端解密 EDEK;
-
簡單使用場景:
-
前提場景:
-
人物:管理員s、用戶a、用戶b、外部無權(quán)人c
- 管理員在hdfs上創(chuàng)建了一個目錄A,讓a來存取文件,而b無權(quán)查看(通過hdfs權(quán)限控制,和Linux上的文件權(quán)限控制一樣)
- 管理員在hdfs上創(chuàng)建了一個目錄B,讓b來存取文件,而A無權(quán)查看
-
沒有透明加密的時候:
正常情況下,通過hdfs客戶端,a只能查看A里的文件;b只能查看B的文件。
但a(或者c)如果通過某種方式,進入hdfs的數(shù)據(jù)塊存儲區(qū)域,直接把B文件的數(shù)據(jù)塊取出來,那么B文件就泄密了 -
有透明加密的時候:
管理員用密鑰1把A目錄設為“加密區(qū)”,用密鑰2把B目錄也設為“加密區(qū)”
當a獲取了B文件的數(shù)據(jù)塊,由于他他沒有A文件的使用權(quán)限,kms不會返回給他密鑰2。
當c獲取了B文件的數(shù)據(jù)塊,由于他也沒有A文件的使用權(quán),kms也不會返回給他密鑰2。
此時就保證了文件B的安全。
注:加密的是數(shù)據(jù)塊,就是存在磁盤上的東西,在hdfs上直接看是自動解密了,加密的要直接取數(shù)據(jù)塊看。
二、環(huán)境準備:
hadoo-2.10.1集群:節(jié)點:node1 node2 node3
三、開始配置
1. KMS server 配置
配置KMS:由于kms是跟hadoop結(jié)合在一起的,故可以直接到hadoop安裝目錄下的etc/hadoop去配置kms的配置文件,kms-site.xml, kms-env.sh,kms-acls.xml
kms-site.xml
用默認配置即可,但是要知道每一項的含義,后面方便去做對應的事情.
- hadoop.kms.key.provider.uri 可以直接理解成我們生成 key 后存儲到的文件位置。后面我們會根據(jù) java 秘鑰生成器 keytool -genkey 去生成一個 key.
- hadoop.security.keystore.java-keystore-provider.password-file 上面那個文件生成的時候,需要指定一個密碼,而這個密碼,需要 kms 從一個文件中讀取。那么這個文件的路徑就是這個屬性的 value.
- KMS Cache
- hadoop.kms.cache.enable
- hadoop.kms.cache.timeout.ms
- hadoop.kms.current.key.cache.timeout.ms
- 配置緩沖區(qū),這樣的話,當獲取 getCurrentKey() and getKeyVersion() andgetMetadata() 的時候 不用每次去訪問 keystore 只用從緩存中讀取就可以。當然,秘鑰更新或者被刪除的時候,會自動更新。
2. 使用 keytool 生成秘鑰
(py38_1.12) lzq@node1 ~ keytool -genkey -alias 'key1'; 輸入密鑰庫口令: 再次輸入新口令: 您的名字與姓氏是什么?[Unknown]: zhiqiang li 您的組織單位名稱是什么?[Unknown]: xxx 您的組織名稱是什么?[Unknown]: xxx 您所在的城市或區(qū)域名稱是什么?[Unknown]: hangzhou 您所在的省/市/自治區(qū)名稱是什么?[Unknown]: zhejiang 該單位的雙字母國家/地區(qū)代碼是什么?[Unknown]: china CN=zhiqiang li, OU=xxx, O=xxx, L=hangzhou, ST=zhejiang, C=china是否正確?[否]: yes 您的名字與姓氏是什么?[zhiqiang li]: zhiqiang li 您的組織單位名稱是什么?[xxx]: xxx 您的組織名稱是什么?[xxx]: xxx 您所在的城市或區(qū)域名稱是什么?[hangzhou]: hangzhou 您所在的省/市/自治區(qū)名稱是什么?[zhejiang]: zhejiang 該單位的雙字母國家/地區(qū)代碼是什么?[china]: china CN=zhiqiang li, OU=xxx, O=xxx, L=hangzhou, ST=zhejiang, C=china是否正確?[否]: 是輸入 <key1> 的密鑰口令(如果和密鑰庫口令相同, 按回車): 再次輸入新口令: Warning: JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore /home/lzq/.keystore -destkeystore /home/lzq/.keystore -deststoretype pkcs12" 遷移到行業(yè)標準格式 PKCS12。密碼默認位置是在你的家目錄下,默認名為.keystore,為隱藏文件,建議使用默認的方式創(chuàng)建密鑰.
-
注:有兩個密碼需要設定,這里我都設置為了123456,首先輸入第一個密碼,其他的隨意寫,直到出現(xiàn)no的時候?qū)憏es,然后輸入第二個密碼。
-
注:密碼默認位置是在你的家目錄下,默認名為.keystore,為隱藏文件,建議使用默認的方式創(chuàng)建密鑰。
-
注:其他方式創(chuàng)建密鑰:(指定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的密鑰存儲數(shù)據(jù)庫了,由于這個keystore有訪問密碼(比如上面所設置的storepass :123456),這個密碼是要告訴kms的,否則kms訪問不了這個keystore,kms通過讀取一個文本文件來獲取密碼。所以我們需要創(chuàng)建一個文本文件,在里面寫上keystore訪問密碼。
上面
輸入密鑰庫口令:
再次輸入新口令:
這兩個輸入的密碼 是 123456 。 放入到一個文件里面 kms.keystore.password
然后把文件放到 kms 服務的 classes 目錄下面
這個文件名和上面 kms-site.xml 里面的 hadoop.security.keystore.java-keystore-provider.password-file 的 value 相對應.
3. 配置 kms-env.sh
# $HADOOP_HOME 需要提前搭建 hadoop 集群的時候就配置好 export KMS_HOME=$HADOOP_HOME export KMS_LOG=${KMS_HOME}/logs/kms export KMS_HTTP_PORT=16000 export KMS_ADMIN_PORT=160014. 啟動 KMS 服務
kms.sh start # 如果沒配置環(huán)境變量,需要去 Hadoop home 里面 sbin 下面的腳本去啟動。此時通過jps能看到Bootstrap進程,表示成功啟動。
可以在配置的目錄里面查看到日志
5. 配置客戶端的 core-site.xml hdfs-site.xml
core-site.xml
node1 ip 是 192.168.178.101, 也可以配置成 kms://http@node116000/kms
<!--KMS 配置--><property><name>hadoop.security.key.provider.path</name><value>kms://http@192.168.178.101:16000/kms</value></property>hdfs-site.xml
<!--KMS 配置--> <property><name>dfs.encryption.key.provider.uri</name><value>kms://http@192.168.178.101:16000/kms</value> </property>6. 重新啟動namenode與datanode
7. 驗證一下 KMS 服務
-
創(chuàng)建之前查看一下
hadoop key create key1
-
創(chuàng)建之后查看一下
hadoop key list -
創(chuàng)建一個加密分區(qū)
hdfs dfs -mkdir /cryptohdfs crypto -createZone -keyName key1 -path /crypto
如果報錯 RemoteException: Can’t create an encryption zone for /crypto since no key provider is available.
那么是因為可能你沒配置對下面的屬性,它在 core-site.xml
然后重啟一下 HDFS 就可以了。
我是因為我命名配置了這個屬性,但是重啟還是不行。 后來源碼 debug 到報錯的地方,突然又好了。 后面也不再出問題了。
很奇怪。就是一直報錯 since no key provider is available
源碼在下面
上面異常 110 行的異常就是命令行的報錯。
provider 的創(chuàng)建就是這個代碼
上面的 keyProviderUriKeyName 其實就是我們配置的 hadoop.security.key.provider.path 屬性。
四、驗證
一個文件上傳到 HDFS 上兩個不同文件夾,一個加密 /crypto, 一個不假面 /no_crypto 。
通過命令找到 datanode 上面的文件塊,
hdfs fsck /crypto/crypto.txt -files -blocks -locations hdfs fsck /no_crypto/crypto.txt -files -blocks -locations我們可以看到, 加密區(qū)域的文件無法查看,不加密區(qū)域的文件直接用 linux cat 命令就可以看到內(nèi)容。
直接通過命令查看文件內(nèi)容
總結(jié)
以上是生活随笔為你收集整理的Hadoop 2.10.1 HDFS 透明加密原理 + 实战 + 验证的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter开发之常用Widget学习
- 下一篇: 浅学socket及iOS中的AsyncS