原生 KMS 模型
概覽
適用場景
- 將 DataNode 上的數(shù)據(jù) block 加密存放若专,這樣即使惡意用戶通過某種方式繞過了權(quán)限控制,或直接訪問了 DataNode窖杀,獲取了其它用戶的數(shù)據(jù) block漓摩,也看不到這些 block 的真實(shí)內(nèi)容。
- 對 HDFS 的讀寫性能會(huì)有一定的降低入客,但應(yīng)該不會(huì)太嚴(yán)重(未測試)管毙,HDFS 優(yōu)先使用 native 的 libcrypto.so 完成加解密(默認(rèn)算法 AES-CTR腿椎,支持128位 AES 加密),新版本的 libcrypto.so 都支持 AES-NI 指令集夭咬,在 CPU 層面有相關(guān)的 AES 指令酥诽,為了使用 AES-NI,要求在所有的客戶端上(包括所有的 map/reduce 客戶端)皱埠,都安裝最新的 libcrypto.so
幾個(gè)關(guān)鍵點(diǎn)
- HDFS client 向 DataNode 寫入/讀取數(shù)據(jù)時(shí)肮帐,數(shù)據(jù)的加密/解密過程都在 client 端的 JVM 中完成,HDFS 集群本身不感知這個(gè)過程边器。
- HDFS client 如果需要開啟加密傳輸训枢,只需要在 core-site.xml 中配置幾個(gè)選項(xiàng)即可,不需要修改現(xiàn)有的業(yè)務(wù)代碼忘巧,整個(gè)加解密功能是作為插件的形式存在的恒界。
- KMS 集群獨(dú)立于 HDFS 集群之外,可以為多個(gè) HDFS 集群所共享砚嘴。
- KMS 集群作為 HDFS 之外的獨(dú)立系統(tǒng)十酣,它的認(rèn)證機(jī)制和 HDFS 是分開的。
幾個(gè)關(guān)鍵概念
EZ(Encrpytion Zone)
加密區(qū)域际长,HDFS 可以將一個(gè)現(xiàn)有的空目錄做成 EZ耸采,在該目錄的 xattr 中會(huì)保存一些相關(guān)的加密信息(例如該 EZ 使用的 EZ key 名字、使用的加密算法工育、使用的協(xié)議版本等等)虾宇,該EZ 下的所有文件在寫入時(shí)都將被自動(dòng)加密,讀取時(shí)都將被自動(dòng)解密如绸,如前所述嘱朽,加解密過程都在 client 端的 jvm 中進(jìn)行。EZ Key(Encryption Zone key)
每個(gè) Encrytion Zone 都關(guān)聯(lián)著一個(gè) root key怔接,這是在該 EZ 創(chuàng)建時(shí)搪泳,由 HDFS 管理員指定關(guān)聯(lián)起來的,EZ Key 由 KMS 產(chǎn)生扼脐、存儲(chǔ)和管理岸军,保存在 KMS 的后備存儲(chǔ)中。DEK(Data Encrpytion Key)
數(shù)據(jù)加密 key谎势,EZ 中的每個(gè)文件都有自己特定的 DEK凛膏,client 讀寫該文件時(shí),需要用該文件的 DEK 進(jìn)行加解密操作脏榆。-
EDEK(Encrypted Data Encryption Key)
文件的 DEK 過于敏感猖毫,不會(huì)保存在任何地方,而是用他所從屬的 EZ 的 EZ Key 進(jìn)行加密须喂,生成一個(gè) EDEK吁断,然后將此 EDEK 保存在該文件的擴(kuò)展屬性中趁蕊,一個(gè) EDEK 的內(nèi)容主要包括該 EDEK 加密時(shí)使用的 EZ Key 名字,EZ Key 版本(同一個(gè) EZ key 可以有多個(gè)版本)仔役、加密后的密文掷伙、加密使用的初始向量等等,后面需要解密 EDEK 時(shí)又兵,需要將這些信息發(fā)送給 KMS Server 進(jìn)行解密處理任柜。- client 創(chuàng)建新文件時(shí),NameNode 會(huì)調(diào)用 KMS 接口沛厨,為該文件產(chǎn)生一個(gè)唯一的 EDEK宙地,并將其保存在該文件的擴(kuò)展屬性中。
- client 讀寫文件時(shí)逆皮,從 NameNode 拿到的都是該文件的 EDEK宅粥,client 需要調(diào)用 KMS 接口,將此 EDEK 解密电谣,拿到真正的 DEK秽梅,然后使用此 DEK 進(jìn)行加解密操作。
這樣設(shè)計(jì)的目的剿牺,是為了保證在 HDFS 中企垦,不保存任何明文密鑰信息,這樣即使惡意用戶攻破了 HDFS牢贸,也只能拿到加密后的文件和加密后的 DEK竹观,依然讀不到文件的原始內(nèi)容镐捧。
-
幾個(gè) key 的關(guān)系如下
關(guān)鍵操作流程分析
-
一個(gè)典型的操作流程如下潜索,其中創(chuàng)建 EZ key、創(chuàng)建 EZ 這兩個(gè)操作需要管理員使用 hadoop shell 手動(dòng)完成:
# 創(chuàng)建 EZ Key
hadoop key create mykey# 創(chuàng)建一個(gè)空目錄懂酱,把這個(gè)空目錄做成 EZ
hdfs dfs -mkdir /zone
hdfs crypto -createZone -keyName mykey -path /zone# 向 EZ 中讀寫文件
hadoop fs -put helloWorld /zone
hadoop fs -cat /zone/helloWorld -
生成 EZ Key
hadoop shell 命令如下:
hadoop key create mykey
-
交互流程
- 創(chuàng)建 EZ竹习,使用上一步生成的 EZ Key,將一個(gè) HDFS 中現(xiàn)有的空目錄做成 Encryption Zone
hadoop shell 命令如下:
hdfs crypto -createZone -keyName mykey -path /zone
-
交互流程
- 在 EZ 中 創(chuàng)建一個(gè)文件
使用正常的 FileSystem API 就可以列牺,和使用普通的 HDFS 沒有區(qū)別整陌。
-
交互流程
- 寫 EZ 中的文件
- 使用正常的 FileSystem API 就可以,和使用普通的 HDFS 沒有區(qū)別瞎领。
-
交互流程
- 讀 EZ 中的文件
- 使用正常的 FileSystem API 就可以泌辫,和使用普通的 HDFS 沒有區(qū)別。
-
交互流程
原生 KMS存在的幾個(gè)問題
EZ key 共享存儲(chǔ)問題
多個(gè) KMS Server 的 backing keystore 并不共享九默,原生 KMS Server 使用的是 JKS(Java KeyStore) 存儲(chǔ)機(jī)制震放,EZ Key 都保存在本地文件系統(tǒng)上的 keyStore 文件中,這樣的話驼修,由于 keyStore 文件無法在多個(gè) KMS Server 之間共享殿遂,導(dǎo)致掛掉任何一個(gè) Server 后诈铛,其它剩余的 KMS Server 都可能讀取不到已有的 EZ Key,導(dǎo)致 EZ key 丟失墨礁,進(jìn)而使得加密文件打不開幢竹。
原生的這種集群組織方式,更像是一種負(fù)載均衡策略恩静,從這種情況下 KMS 客戶端的名字也能看的出來:LoadBalancingKMSClientProvider焕毫。在 Hadoop 的官方文檔中,也強(qiáng)調(diào)了 JKS 這種存儲(chǔ)機(jī)制不能用在生產(chǎn)環(huán)境中驶乾。
這個(gè)地方需要實(shí)現(xiàn)一個(gè)新的分布式的咬荷、共享存儲(chǔ)的 backing keyStore 方式,可以使用 zookeeper 或者 ratis 等等轻掩。Apache Zookeeper 和 Apache Ratis 的比較:
Apache zookeeper | Apache ratis | |
---|---|---|
協(xié)議 | ZAB(Zookeeper Atomic Broadcast protocol) | Raft |
成熟度 | 項(xiàng)目成熟幸乒,使用廣泛 | 項(xiàng)目較新,應(yīng)用不多唇牧,目前 OZone 的多副本存儲(chǔ)使用了 Ratis |
一致性保證 | 順序一致性罕扎,單個(gè) KMS Server 可能讀到較老數(shù)據(jù),但可借助 watch 機(jī)制和 sync 原語實(shí)現(xiàn)強(qiáng)一致性 | 強(qiáng)一致性 |
緩存友好度 | 借助 watch 機(jī)制和 sync 原語丐重,可以實(shí)現(xiàn)多個(gè) KMS Server 的緩存一致性 | 沒有主動(dòng)通知機(jī)制腔召,無法保證多個(gè) KMS Server 的緩存一致 |
目前的話,還是建議:
- 選擇 Zookeeper扮惦。
- 使用緩存提高性能臀蛛,同時(shí)借助 Zookeeper 的 watch 機(jī)制和 sync 原語,保證多個(gè) KMS Server 的緩存一致性崖蜜。
Move 問題
在普通的 HDFS 目錄之間浊仆,文件的 move 并不涉及到數(shù)據(jù)的移動(dòng),僅僅是元數(shù)據(jù)的修改豫领,速度非陈帐粒快,但在 EZ 和非 EZ 之間等恐、不同 EZ 之間洲劣,并不支持 move 操作,只支持 copy 操作课蔬,相對較慢囱稽,具體如下圖所示:
這其中的原因是,HDFS client 無論 create二跋、append 還是 open 一個(gè)文件時(shí)战惊,如果發(fā)現(xiàn)這個(gè)文件是一個(gè)加密文件,那就需要特殊處理同欠,而判斷文件是否加密及隨后正確的加解密處理(寫入需要加密样傍、讀取需要解密)横缔,需要來自兩方面的信息:
- 來自該文件本身的 xattr 的信息,即該文件的 EDEK衫哥。
- 來自該文件所處的 EZ 根目錄的 xattr 信息茎刚,包括加解密算法、協(xié)議版本等等撤逢。
既然如此膛锭,那么:
- 對整個(gè) EZ(即 EZ 根目錄)做 move 操作是可以的,這可以保證上面所說的兩部分信息都保存下來蚊荣。
- 將文件從非 EZ move 到 EZ 中初狰,由于該文件本身沒有 EDEK,最終它會(huì)被當(dāng)成普通文件讀寫互例,邏輯上雖然行的通奢入,但這違背了 EZ 本身的語義,因此這種操作不被允許媳叨。
- 將文件從 EZ move 到非 EZ 中为迈,由于缺失了 EZ 根目錄的 xattr分瘾,也會(huì)導(dǎo)致該文件被當(dāng)做普通文件對待,導(dǎo)致無法讀取真實(shí)內(nèi)容噩翠,后續(xù)寫入的內(nèi)容也缺失了加密過程使得文件內(nèi)容混亂狈涮,因此這種操作也不被允許絮姆。
- 在不同 EZ 之間 move 文件也不可以伊履,出于一些安全考慮蝙茶,HDFS 直接禁止了這種操作。
回收站問題
如前所述汞舱,EZ 和 非 EZ 之間的 move 操作是禁止的伍纫,換句話說 Trash 功能對 EZ 中的文件是不可用的,而在 TDWHadoop 中兵拢,數(shù)據(jù)保護(hù)功能默認(rèn)打開(配置項(xiàng) hadoop.tdw.protect.data.enable 默認(rèn)為 true)翻斟,客戶端的 delete 操作實(shí)際上最終是一個(gè) move 操作,既然 move 被禁止说铃,那么最終表現(xiàn)為EZ 中的文件無法刪除。
這個(gè)問題在 Hadoop 2.8.0 中得到解決嘹履,解決思路如下:
- 為每一個(gè) EZ 單獨(dú)配置一個(gè) Trash 目錄腻扇,例如,假設(shè) EZ 為 /zone砾嫉,則為其配置的 Trash 為 /zone/.Trash幼苛,用戶 root 對應(yīng)的回收站就是 /zone/.Trash/root/,其它用戶類似焕刮。
- 啟用 Trash 功能后舶沿,如果整個(gè) EZ 被刪除墙杯,那整個(gè) EZ 目錄將被 move 到 /user/$USER/.Trash/ 下,此時(shí)和正常目錄的刪除沒有區(qū)別括荡。
- 如果 EZ 中的文件被刪除高镐,則它將被移到 EZ 自己的 Trash 目錄下,例如 root 用戶刪除 /zone/file.txt 將會(huì)把 /zone/file.txt move 為 /zone/.Trash/root/Current/zone/file.txt畸冲。
- 無論是 EZ 自己的 Trash 目錄嫉髓,還是 /user/$USER/ 下面的 Trash 目錄,都遵循 HDFS Trash 的 checkpoint 規(guī)則邑闲,過期的文件將被自動(dòng)清理算行。