天天看點

hdfs的透明加密記錄

作者:huan1993

1、背景

我們知道,在hdfs中,我們的資料是以block塊存儲在我們的磁盤上的,那麼預設情況下,它是以密文存儲的,還是以明文存儲的呢?如果是明文存儲的,那麼是否就不安全呢?那麼在hdfs中是如何做才能做到資料的透明加密呢?

2、常見的加密層級

hdfs的透明加密記錄

常見的加密層級

  1. 應用層加密: 這是最安全和最靈活的方法。加密内容最終由應用程式來控制。并且可以精确的反應使用者的需求。但是,編寫應用程式來實作加密一般都比較困難。
  2. 資料庫層加密: 類似于應用程式級加密。大多數資料庫供應商都提供某種形式的加密。但是可能存在性能問題。比如:索引無法加密。
  3. 檔案系統層加密: 這種方式對性能影響不大,且對應用程式是透明的,一般也比較容易實施。但是如果需要應對細粒度的要求政策,可能無法完全滿足。比如:加密檔案系統(EFS)用于在(NTFS)檔案系統卷上存儲已加密的檔案。
  4. 磁盤層加密: 易于部署和高性能,但是相當不靈活,隻能防止使用者從實體層面盜竊資料。

3、透明加密介紹

  • HDFS透明加密(Transparent Encryption)支援端對端的透明加密,啟用以後,對于一些需要加密的HDFS目錄裡的檔案可以實作透明的加密和解密,而不需要修改使用者的業務代碼。端對端是指加密和解密隻能通過用戶端來操作。
  • 對于加密區域裡的檔案,HDFS儲存的即是加密後的檔案,檔案加密的密鑰也是加密的。讓非法使用者即使從作業系統層面拷走檔案,也是密文,沒法檢視。
  • HDFS叢集管理和密鑰的管理是互相獨立的職責,由不同的使用者角色(HDFS管理者、密鑰管理者)承擔。
  • 隻有HDFS用戶端可以加密或解密資料,密鑰管理在HDFS外部,HDFS無法通路未加密的資料或加密密鑰。

4、HDFS透明加密的核心概念

4.1 加密區域

加密區域就是HDFS上的一個目錄,隻不過該目錄相對而言稍微特殊點。 檔案寫入的時候會被透明加密,檔案讀取的時候會被透明解密。

4.2 加密區域密鑰-EZ KEY

當加密區域被建立時,都會有一個加密區域密鑰(EZ密鑰, encryption zone key)與之對應,EZ密鑰存儲在HDFS外部的密鑰庫中。

hdfs的透明加密記錄

4.3 資料加密密鑰-DEK

加密區域裡的每個檔案都有其自己的加密密鑰,叫做資料加密密鑰(DEK, data. encryption key)。

hdfs的透明加密記錄

DEK

4.4 加密資料加密密鑰 EDEK

DEK會使用其各自的加密區域的EZ密鑰進行加密,以形成 加密資料加密密鑰(EDEK)

hdfs的透明加密記錄

EDEK

4.5 DEK的加解密和檔案的加解密

hdfs的透明加密記錄

DEK的加解密和檔案的加解密

4.6 密鑰庫

  • 存儲密鑰(key)的叫做密鑰庫(keystore),将HDFS與外部企業級密鑰庫(keystore)內建是部署透明加密的第一步。
  • 為什麼密鑰庫獨立與HDFS之外? 可以指責分離,而且也更加安全。 這樣hdfs管理者和keystore管理者就是2個人,各個處理各自的事情。

4.7 KMS 密鑰管理服務

  • Hadoop密鑰管理服務(Key Management Server,簡稱KMS),用作HDFS用戶端與密鑰庫之間的代理。
  • KMS主要有以下幾個職責
  1. 通路加密區域密鑰(EZ Key)
  2. 生成EDEK,EDEK存儲在NameNode上
  3. 為HDFS用戶端解密EDEK

5、配置透明加密

5.1 關閉hdfs叢集

[hadoopdeploy@hadoop01 sh]$ stop-dfs.sh
Stopping namenodes on [hadoop01]
Stopping datanodes
Stopping secondary namenodes [hadoop03]
[hadoopdeploy@hadoop01 sh]$
           

5.2 建立keystore

密鑰庫的密碼為Hadoop@123

[hadoopdeploy@hadoop01 ~]$ keytool -genkey -alias 'keystore_hadoop'
輸入密鑰庫密碼:
再次輸入新密碼:
您的名字與姓氏是什麼?
  [Unknown]:
您的組織機關名稱是什麼?
  [Unknown]:
您的組織名稱是什麼?
  [Unknown]:
您所在的城市或區域名稱是什麼?
  [Unknown]:
您所在的省/市/自治區名稱是什麼?
  [Unknown]:
該機關的雙字母國家/地區代碼是什麼?
  [Unknown]:
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
  [否]:  y

輸入 <keystore_hadoop> 的密鑰密碼
 (如果和密鑰庫密碼相同, 按回車):
再次輸入新密碼:

Warning:
JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore /home/hadoopdeploy/.keystore -destkeystore /home/hadoopdeploy/.keystore -deststoretype pkcs12" 遷移到行業标準格式 PKCS12。
[hadoopdeploy@hadoop01 ~]$ ll ~/.keystore
-rw-rw-r--. 1 hadoopdeploy hadoopdeploy 1992 6月  15 22:20 /home/hadoopdeploy/.keystore
[hadoopdeploy@hadoop01 ~]$
           
hdfs的透明加密記錄

生成keystore

5.3 編輯 kms-site.xml檔案

<configuration>
        <!-- 設定密鑰庫的提供者,jceks:辨別的是java密鑰庫  -->
        <property>
                <name>hadoop.kms.key.provider.uri</name>
                <value>jceks://file@/${user.home}/kms.jks</value>
        </property>
        <!-- 密鑰庫的密碼檔案,該檔案中儲存的是通路密鑰庫的密碼, 需要放置在hadoop的配置檔案夾下 ...../etc/hadoop -->
        <property>
                <name>hadoop.security.keystore.java-keystore-provider.password-file</name>
                <value>kms.keystore.password.txt</value>
        </property>
        <property>
                <name>hadoop.kms.http.port</name>
                <value>16000</value>
        </property>
        <!-- 對外暴露的kms服務位址 -->
        <property>
                 <name>dfs.encryption.key.provider.uri</name>
                 <value>kms://http@hadoop01:16000/kms</value>
        </property>
        <!-- 認證方式 -->
        <property>
                <name>hadoop.kms.authentication.type</name>
                <value>simple</value>
        </property>
</configuration>
           

需要建立kms.keystore.password.txt檔案,并設定密鑰庫的密碼

[hadoopdeploy@hadoop01 hadoop]$ cat /opt/bigdata/hadoop-3.3.4/etc/hadoop/kms.keystore.password.txt
Hadoop@123
[hadoopdeploy@hadoop01 hadoop]$
           

5.4 編輯 kms-env.sh

export KMS_HOME=/opt/bigdata/hadoop-3.3.4
export KMS_LOG=${KMS_HOME}/logs/kms
export KMS_ADMIN_PORT=16001
           

5.5 修改core-site.xml

<!-- 指定通路kms服務的位址  -->
<property>
    <name>hadoop.security.key.provider.path</name>
    <value>kms://http@hadoop01:16000/kms</value>
</property>
           

5.6 修改hdfs-site.xml

<!-- 指定通路kms服務的位址 -->
<property>
    <name>dfs.encryption.key.provider.uri</name>
    <value>kms://http@hadoop01:16000/kms</value>
</property>
           

5.7 同步配置到叢集另外的機器上

[hadoopdeploy@hadoop01 hadoop]$ scp kms-site.xml kms-env.sh core-site.xml hdfs-site.xml hadoop01:$PWD
[hadoopdeploy@hadoop01 hadoop]$ scp kms-site.xml kms-env.sh core-site.xml hdfs-site.xml hadoop02:$PWD
           

5.8 啟動hdfs叢集

[hadoopdeploy@hadoop01 hadoop]$ start-dfs.sh
Starting namenodes on [hadoop01]
Starting datanodes
Starting secondary namenodes [hadoop03]
[hadoopdeploy@hadoop01 hadoop]$ jps
2080 NameNode
2243 DataNode
2471 Jps
[hadoopdeploy@hadoop01 hadoop]$
           

5.9 啟動kms服務

[hadoopdeploy@hadoop01 hadoop]$ hadoop --daemon start kms
WARNING: KMS_LOG has been replaced by HADOOP_LOG_DIR. Using value of KMS_LOG.
WARNING: /opt/bigdata/hadoop-3.3.4//temp does not exist. Creating.
WARNING: /opt/bigdata/hadoop-3.3.4/logs/kms does not exist. Creating.
[hadoopdeploy@hadoop01 hadoop]$ jps
2080 NameNode
2243 DataNode
2870 KMSWebServer
2904 Jps
[hadoopdeploy@hadoop01 hadoop]$
           

hadoop --daemon stop kms 停止kms服務

6、測試透明加密

需求: 在hdfs上建立2個目錄logs和datas,隻要是在datas目錄中上傳檔案都需要透明加密,logs目錄不需要,同時往logs和datas目錄中上傳一個檔案,然後檢視對應檔案在磁盤上的block塊,直接在作業系統上檢視這個塊,看檔案是否加密。

6.1 準備資料

[hadoopdeploy@hadoop01 hadoop]$ hadoop fs -mkdir /logs
[hadoopdeploy@hadoop01 hadoop]$ hadoop fs -mkdir /datas
[hadoopdeploy@hadoop01 hadoop]$ hadoop fs -ls /
Found 2 items
drwxr-xr-x   - hadoopdeploy supergroup          0 2023-06-16 21:10 /datas
drwxr-xr-x   - hadoopdeploy supergroup          0 2023-06-16 21:10 /logs
[hadoopdeploy@hadoop01 hadoop]$ echo 123456789 > 1.data
[hadoopdeploy@hadoop01 hadoop]$ cat 1.data
123456789
[hadoopdeploy@hadoop01 hadoop]$
           

在 / 目錄下建立2個檔案夾 logs和datas, 并建立一個檔案1.data,内容為123456789, 1.data先不傳遞到logs和datas目錄中。

6.2 建立key

# 建立一個key ,名字是 ezk_datas
[hadoopdeploy@hadoop01 hadoop]$ hadoop key create ezk_datas
ezk_datas has been successfully created with options Options{cipher='AES/CTR/NoPadding', bitLength=128, description='null', attributes=null}.
org.apache.hadoop.crypto.key.kms.LoadBalancingKMSClientProvider@3d5c822d has been updated.
# 檢視key 清單
[hadoopdeploy@hadoop01 hadoop]$ hadoop key list -metadata
Listing keys for KeyProvider: org.apache.hadoop.crypto.key.kms.LoadBalancingKMSClientProvider@2f8dad04
ezk_datas : cipher: AES/CTR/NoPadding, length: 128, description: null, created: Fri Jun 16 21:36:51 CST 2023, version: 1, attributes: [key.acl.name=ezk_datas]
[hadoopdeploy@hadoop01 hadoop]$
           

6.3 建立加密區域

[hadoopdeploy@hadoop01 hadoop]$ hdfs crypto -createZone -keyName ezk_datas -path /datas
Added encryption zone /datas
[hadoopdeploy@hadoop01 hadoop]$
           

ezk_datas: 為我們建立的ezk的名字

/datas: hdfs上的一個目錄

6.4 檔案上傳

# 往/datas目錄上傳一個檔案
[hadoopdeploy@hadoop01 hadoop]$ hadoop fs -put 1.data /datas
# 往/logs目錄上傳一個檔案
[hadoopdeploy@hadoop01 hadoop]$ hadoop fs -put 1.data /logs
[hadoopdeploy@hadoop01 hadoop]$
           

6.5 檢視加密檔案

hdfs的透明加密記錄

檢視加密檔案

7、參考資料

1、https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/TransparentEncryption.html