CredentialProvider API 是用於插入可擴充憑證提供者的 SPI 架構。憑證提供者用於將敏感權杖、機密和密碼的使用與其儲存和管理的詳細資料分開。選擇各種儲存機制來保護這些憑證的能力使我們能夠將這些敏感資產遠離純文字,遠離窺探,並可能由第三方解決方案管理。
本文檔旨在說明 CredentialProvider API 的設計、現成的實作、它們的使用位置以及如何採用其使用。
讓我們快速概述一下憑證提供者架構在 Hadoop 中保護密碼或其他敏感權杖的使用。
某些部署對密碼等敏感權杖在叢集中的儲存和管理方式非常敏感。例如,可能實施了安全最佳實務和政策,要求此類權杖永遠不要以明文儲存。企業部署可能需要使用首選的解決方案來管理憑證,而我們需要一種方式為其插入整合。
Hadoop 專案和生態系統中有許多地方可以使用憑證提供者 API,而且數量持續增加。一般而言,使用模式包含相同的需求和流程。
hadoop.security.credential.provider.path
是由一個或多個憑證提供者 URI 組成的逗號分隔清單,在嘗試解析憑證別名時會遍歷此清單。
org.apache.hadoop.conf.Configuration
類別用於設定或對憑證提供者有其他內部用途的功能或元件,可能會選擇使用 CredentialProvider
API 本身。可以在 Configuration.getPassword 及其單元測試中找到其使用範例。範例:ssl.server.keystore.password
hadoop credential create ssl.server.keystore.password -value 123 \ -provider localjceks://file/home/lmccay/aws.jceks
別名名稱與用於從 Configuration.get()
方法取得憑證的組態屬性相同。
現在,我們需要確定在執行階段,Configuration.getPassword 方法知道此已配置憑證儲存。如果沒有憑證提供者路徑組態,則 Configuration.getPassword()
會略過憑證提供者 API 查詢。因此,務必在 core-site.xml
或元件等效檔案中組態下列內容。
<property> <name>hadoop.security.credential.provider.path</name> <value>localjceks://file/home/lmccay/aws.jceks</value> <description>Path to interrogate for protected credentials.</description> </property>
關於提供者路徑的幾個其他注意事項
localjceks
提供者不依賴 Hadoop 檔案系統 API。有時需要避免遞迴依賴。由 jceks
表示的另一個提供者確實使用 Hadoop 檔案系統 API,且可以支援在 HDFS 或其他相容檔案系統中配置的金鑰儲存。第三種提供者類型是 user
類型。此提供者可以管理儲存在流程憑證檔案中的憑證。總之,首先將憑證配置到提供者中,然後組態提供者以供功能或元件使用,且通常會透過使用 Configuration.getPassword 方法來選取。
功能/元件 | 說明 | 連結 |
---|---|---|
LDAPGroupsMapping | LDAPGroupsMapping 用於在 LDAP 中查詢特定使用者的群組。憑證提供者 API 用於保護 LDAP 繫結密碼和 SSL 所需的密碼。 | LDAP 群組對應 |
SSL 密碼 | FileBasedKeyStoresFactory 利用憑證提供者 API 來解析 SSL 相關密碼。 | 待辦事項 |
HDFS | DFSUtil 使用 Configuration.getPassword() 使用憑證提供者 API 和/或回退到儲存在 ssl-server.xml 中的明文值。基於 Zookeeper 的聯盟狀態儲存和故障轉移控制器使用 Configuration.getPassword 來取得 Zookeeper 驗證資訊,並提供回退到明文驗證資訊的功能。 |
待辦事項 |
YARN | WebAppUtils 透過 Configuration 中稱為 getPassword 的新方法來使用憑證提供者 API。這提供了在 ssl-server.xml 檔案中以明文儲存密碼的替代方案,同時維持向後相容性。基於 Zookeeper 的資源管理員狀態儲存使用 Configuration.getPassword 來取得 Zookeeper 驗證資訊,並提供回退到明文驗證資訊的功能。 | 待辦事項 |
KMS | 使用 HttpServer2.loadSSLConfiguration,它利用 Configuration.getPassword 來讀取 SSL 相關憑證。這些憑證可能會透過憑證提供者和/或從設定檔中的明文(如果允許)來解析。 | KMS |
HttpFS | 使用 HttpServer2.loadSSLConfiguration,它利用 Configuration.getPassword 來讀取 SSL 相關憑證。這些憑證可能會透過憑證提供者和/或從設定檔中的明文(如果允許)來解析。 | HttpFS 伺服器設定 |
AWS S3A |
使用 Configuration.getPassword 來取得 S3 憑證。這些憑證可能會透過憑證提供者 API 或從設定檔中解析,以維持向後相容性。 |
AWS S3/S3A 使用 |
Azure WASB |
使用 Configuration.getPassword 來取得 WASB 憑證。這些憑證可能會透過憑證提供者 API 或從設定檔中解析,以維持向後相容性。 |
Azure WASB 使用 |
Azure ADLS |
使用 Configuration.getPassword 來取得 ADLS 憑證。這些憑證可能會透過憑證提供者 API 或從設定檔中解析,以維持向後相容性。 |
Azure ADLS 使用 |
Apache Accumulo |
Tracer 使用 trace.password 屬性來向 Accumulo 驗證並將追蹤記錄保存在追蹤記錄資料表中。憑證提供者 API 用於從提供者或設定檔中取得 trace.password,以維持向後相容性。 | 待辦事項 |
Apache Slider |
已新增一個功能到 Slider,以提示使用者輸入必要的密碼並使用 CredentialProvider 儲存這些密碼,以便應用程式稍後可以擷取這些密碼。 | 待辦事項 |
Apache Hive |
已透過使用憑證提供者 API 來保護 Metastore 密碼、SSL 相關密碼和 JDO 字串密碼。 | 待辦事項 |
Apache HBase |
HBase RESTServer 使用新的 Configuration.getPassword 方法,以便會先檢查憑證提供者 API,然後在允許的情況下回退到明文。 | 待辦事項 |
Apache Oozie |
使用憑證提供者 API 來保護 SSL、電子郵件和 JDBC 密碼。 | 待辦事項 |
Apache Ranger |
使用憑證提供者 API 來保護資料庫、信任和金鑰庫密碼。 | 待辦事項 |
hadoop credential
命令用法:hadoop credential <子命令> [選項]
請參閱 命令手冊 中的命令選項詳細資料
憑證命令可用於向特定憑證儲存提供者提供密碼或機密。若要明確指出要使用的提供者儲存,應使用 -provider
選項。
範例:hadoop credential create ssl.server.keystore.password -provider jceks://file/tmp/test.jceks
若要指出特定提供者類型和位置,使用者必須在 core-site.xml 中提供 hadoop.security.credential.provider.path
組態元素,或在每個憑證管理命令上使用命令列選項 -provider
。此提供者路徑是 URL 的逗號分隔清單,用於指出應諮詢的提供者清單的類型和位置。例如,下列路徑:user:///,jceks://file/tmp/test.jceks,jceks://hdfs@nn1.example.com/my/path/test.jceks
指出應透過使用者提供者諮詢目前使用者的憑證檔案,位於 /tmp/test.jceks
的本機檔案是 Java 金鑰庫提供者,而位於 HDFS 中的檔案 nn1.example.com/my/path/test.jceks
也是 Java 金鑰庫提供者的儲存。
UserProvider
由提供者 URI user:///
表示,用於從使用者的憑證檔案擷取憑證。此檔案用於儲存執行作業和應用程式所需的各種權杖、機密和密碼。JavaKeyStoreProvider
由提供者 URI jceks://SCHEME/path-to-keystore
表示,用於從檔案系統 <SCHEME>
中的 Java 金鑰庫檔案擷取憑證。Hadoop 檔案系統 API 的基礎用途允許將憑證儲存在本機檔案系統或群集儲存中。LocalJavaKeyStoreProvider
由提供者 URI localjceks://file/path-to-keystore
表示,用於從必須儲存在本機檔案系統中的 Java 金鑰庫存取憑證。這對於會導致遞迴相依性以存取 HDFS 的憑證是必要的。任何時候您的憑證需要存取 HDFS,我們都不能依賴從 HDFS 取得憑證來執行此動作。BouncyCastleFIPSKeyStoreProvider
由提供者 URI bcfks://SCHEME/path-to-keystore
表示,用於從檔案系統 <SCHEME>
中的 Bouncy Castle FIPS 金鑰庫檔案擷取憑證。Hadoop 檔案系統 API 的基礎用途允許將憑證儲存在本機檔案系統或群集儲存中。LocalBcouncyCastleFIPSKeyStoreProvider
,由提供者 URI localbcfks://file/path-to-keystore
表示,用於存取必須儲存在本機檔案系統中的 Bouncy Castle FIPS 金鑰庫中的憑證。這對於會導致遞迴依賴存取 HDFS 的憑證是必要的。任何時候,如果您的憑證需要存取 HDFS,我們無法依賴從 HDFS 取得憑證來執行此動作。當憑證儲存在檔案系統中時,會套用下列規則
儲存在本機 localjceks://
或 localbcfks://
檔案中的憑證會在讀取設定檔的過程中載入。對於在 YARN 應用程式中使用,這表示它們必須在整個叢集中可見,在主機的本機檔案系統中。
使用 jceks://
或 bcfks://
提供者儲存的憑證可以儲存在叢集檔案系統中,因此在整個叢集中可見,但不能在需要特定憑證才能存取的檔案系統中。
若要將檔案系統 URI 包裝在 jceks
URI 中,請遵循下列步驟。Bouncy Castle FIPS 提供者遵循類似的步驟,將 jceks
取代為 bcfks
,並設定 OS/JDK 層級 FIPS 提供者。
hdfs://namenode:9001/users/alice/secrets.jceks
jceks://
:jceks://hdfs://namenode:9001/users/alice/secrets.jceks
://
字串替換為 @
符號:jceks://hdfs@namenode:9001/users/alice/secrets.jceks
範例
對於本機檔案系統,例如 file:///tmp/secrets.jceks
的路徑會變成:jceks://file/tmp/secrets.jceks
路徑 URI | jceks URI |
---|---|
hdfs://namenode.example.org:9001/user/alice/secret.jceks |
jceks://hdfs@namenode.example.org:9001/user/alice/secret.jceks |
file:///tmp/secrets.jceks |
jceks://file/tmp/secret.jceks |
s3a://container1/secrets/secret.jceks |
jceks://s3a@container1/secrets/secret.jceks |
wasb://account@container/secret.jceks |
jceks://wasb@account@container/secret.jceks |
abfs://account@container/secret.jceks |
jceks://abfs@account@container/secret.jceks |
https://user:pass@service/secret.jceks?token=aia |
jceks://https@user:pass@service/secret.jceks?token=aia |
請注意,為了避免無限遞迴,例如 abfs
、s3a
、adls
和 wasb
等檔案系統會明確排除儲存在其自己檔案系統架構路徑上的金鑰庫,即使它們儲存在使用與正在查詢的憑證不同的憑證組的容器中。
例如,您無法使用儲存在 s3a://shared/secrets/secret.jceks
中的憑證來讀取容器 s3a://private/
的憑證。
Java 中的金鑰庫通常受密碼保護。基於金鑰庫的憑證提供者的主要保護方法是作業系統層級的檔案權限以及可能存在的任何其他針對目標檔案系統的基於政策的存取保護。雖然密碼並非主要的保護來源,但了解管理這些密碼所需的機制和可用的選項非常重要。了解所有需要存取用於保護金鑰庫的密碼才能在執行階段使用它們的各方也很重要。
選項 | 說明 | 注意事項 |
---|---|---|
預設密碼 | 這是硬編碼的密碼「none」。 | 這是開放原始碼專案中硬編碼的密碼,因此有明顯的缺點。然而,機制部分將顯示它更簡單,因此幾乎與其他更複雜的選項一樣安全。 |
環境變數 | HADOOP_CREDSTORE_PASSWORD |
此選項使用環境變數來傳達在查詢 hadoop.security.credential.provider.path 組態屬性中設定的所有金鑰庫時應使用的密碼。路徑中所有基於金鑰庫的提供者都需要受同一個密碼保護。 |
密碼檔案 | hadoop.security.credstore.java-keystore-provider.password-file |
此選項使用「側邊檔案」,其位置在 hadoop.security.credstore.java-keystore-provider.password-file 組態屬性中設定,以傳達在查詢 hadoop.security.credential.provider.path 組態屬性中設定的所有金鑰庫時應使用的密碼。 |
極其重要的是要考慮受保護憑證的所有執行階段使用者(mapreduce 工作/應用程式)都需要存取用於保護金鑰庫提供者的密碼。傳達此密碼的方法有很多,它們在上面的「選項」部分中說明。
金鑰庫密碼 | 說明 | 需要同步 | 明文 | 檔案權限 |
---|---|---|---|---|
預設密碼 | 預設為硬編碼密碼。基本上,當對所有基於金鑰庫的憑證儲存庫使用預設密碼時,我們會利用檔案權限來保護憑證儲存庫,而金鑰庫密碼只是儲存金鑰庫的形式。 | 否 | 是 | 否 (已記錄) |
環境變數 | HADOOP_CREDSTORE_PASSWORD 環境變數必須設定為所有金鑰庫的自訂密碼,這些金鑰庫可能會在需要從基於金鑰庫的憑證提供者存取憑證的任何程序的提供者路徑中設定。整個逗號分隔提供者路徑只有一個環境變數。很難知道每個金鑰庫所需的密碼,建議對所有基於金鑰庫的憑證提供者使用相同的密碼以避免此問題。設定環境變數可能會需要從腳本或其他明文儲存機制設定。 |
是 | 是 | 否 |
密碼檔案 | hadoop.security.credstore.java-keystore-provider.password-file 設定屬性必須設定為「側邊檔案」的位置,其中包含所有金鑰庫的自訂密碼,這些金鑰庫可能會在提供者路徑中設定。任何需要從基於金鑰庫的憑證提供者存取憑證的程序都需要將此設定屬性設定為適當的檔案位置。整個逗號分隔提供者路徑只有一個密碼檔案。很難知道每個金鑰庫所需的密碼,因此建議對所有基於金鑰庫的憑證提供者使用相同的密碼以避免此問題。密碼檔案是需要管理的其他檔案,以明文儲存密碼,並且需要設定檔案權限,以便只有需要存取的人員才能存取。如果檔案權限設定不當,則存取金鑰庫的密碼會以明文提供。 |
是 | 是 | 是 |
使用預設密碼表示不需要與執行時期使用者進行額外的通訊/同步。預設密碼已知,但檔案權限是金鑰庫的主要保護措施。
與「側邊檔案」不同,當檔案權限受到阻撓時,即使知道密碼,也沒有標準工具可以揭露受保護的憑證。Keytool 需要六個字元或以上的密碼,而且不知道如何從金鑰庫中擷取一般機密。它也僅限於 PKI 金鑰對。編輯器不會揭露儲存在金鑰庫中的機密,cat
、more
或任何其他標準工具也不會。這就是為什麼金鑰庫提供者比「側邊檔案」儲存憑證更好。
話雖如此,對某人來說,使用 API 存取儲存在基於金鑰庫的憑證提供者中的憑證是很容易的。再次強調,當使用預設密碼時,密碼只是儲存金鑰庫的形式。唯一的保護措施是檔案權限和作業系統層級存取政策。
使用者可以決定使用密碼「側邊檔案」來儲存金鑰庫本身的密碼,這是受支援的。只是真的非常需要了解此正確性層級所需的機制。
如果沒有憑證提供者,或找不到金鑰,Credentials.getPassword()
作業會回退至使用組態 XML 檔案中的項目。
可以透過將組態選項 hadoop.security.credential.clear-text-fallback
從 true
變更為 false
來停用此動作
<property> <name>hadoop.security.credential.clear-text-fallback</name> <value>false</value> <description> true or false to indicate whether or not to fall back to storing credential password as clear text. The default value is true. This property only works when the password can't not be found from credential providers. </description> </property>
設定後,所有透過 getPassword()
API 查詢的組態選項都必須透過憑證提供者提供。