CredentialProvider API ガイド

概要

CredentialProvider API は、拡張可能な資格情報プロバイダをプラグインするための SPI フレームワークです。資格情報プロバイダは、機密性の高いトークン、シークレット、パスワードの使用を、それらのストレージと管理の詳細から分離するために使用されます。これらの資格情報を保護するためのさまざまなストレージメカニズムを選択できることで、このような機密性の高い資産をクリアテキストから遠ざけ、覗き見から保護し、サードパーティソリューションで管理できるようになります。

このドキュメントでは、CredentialProvider API の設計、既製の実装、それらが使用される場所、およびその使用方法について説明します。

使い方

使用概要

Hadoop でパスワードやその他の機密性の高いトークンを保護するための資格情報プロバイダフレームワークの使用について、簡単な概要を提供します。

なぜ使用するのか?

クラスター内でパスワードなどの機密性の高いトークンがどのように保存および管理されるかに非常に敏感なデプロイメントがあります。たとえば、クリアテキストで保存してはならないなどのセキュリティベストプラクティスやポリシーが存在する場合があります。エンタープライズデプロイメントでは、資格情報の管理に推奨されるソリューションを使用する必要がある場合があり、それらの統合をプラグインする方法が必要です。

一般的な使用パターン

Hadoop プロジェクトとエコシステムには、今日、資格情報プロバイダ API を利用できる場所が多数あり、その数は増え続けています。一般に、使用パターンは同じ要件とフローで構成されます。

  1. プロバイダ固有のストア内に資格情報をプロビジョニングします。このプロビジョニングは、hadoop credential コマンドまたはプロバイダ固有の管理ツールによって実行される場合があります。
  2. 資格情報プロバイダパスプロパティを設定します。プロバイダパスプロパティ hadoop.security.credential.provider.path は、資格情報エイリアスの解決を試行する際にトラバースされる、1 つ以上の資格情報プロバイダ URI のカンマ区切りリストです。
    • このプロパティは、core-site.xml 内、または core-site.xml とマージされるコンポーネント固有の設定ファイル内で設定できます。
    • DistCp のようなコマンドラインインターフェイスの場合、プロパティは Hadoop システムプロパティ(“-D property=value”)で追加でき、Configuration に動的に追加できます。
  3. 新しいConfiguration.getPasswordメソッドを利用して資格情報を解決する機能またはコンポーネントは、資格情報プロバイダ API のサポートを自動的に取得します。
    • 既存のクリアテキストパスワードに使用されているものと同じプロパティ名を使用することで、このメカニズムにより、クリアテキストとの下位互換性を維持しながら、資格情報プロバイダへの移行が可能になります。
    • 設定内のクリアテキストパスワードにフォールバックする前に、資格情報プロバイダパス全体が照会されます。
  4. 設定に Hadoop の 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>

プロバイダパスに関するその他の注意点

  1. スキームはプロバイダのタイプを示すために使用されます。上記の場合、localjceksプロバイダは Hadoop FileSystem API に依存関係がなく、再帰的な依存関係を回避するために必要な場合があります。jceksで表される別のプロバイダは、Hadoop FileSystem API を使用し、HDFS またはその他の互換性のあるファイルシステム内にプロビジョニングされたキーストアをサポートできます。3 番目のプロバイダタイプはuserタイプです。このプロバイダは、プロセスの資格情報ファイル内に格納された資格情報を管理できます。
  2. パス設定は、プロバイダまたは資格情報ストアのカンマ区切りパスを受け入れます。Configuration.getPasswordメソッドは、エイリアスを解決するかリストを使い果たすまで、各プロバイダを順番に照会します。資格情報のランタイムニーズに応じて、チェックするプロバイダのチェーンを設定する必要がある場合があります。

要約すると、まず、資格情報をプロバイダにプロビジョニングし、次に機能またはコンポーネントで使用するようにプロバイダを設定すると、多くの場合、Configuration.getPasswordメソッドの使用を通じて取得されます。

サポートされている機能
機能/コンポーネント 説明 リンク
LDAPGroupsMapping LDAPGroupsMapping は、LDAP で特定のユーザーのグループを検索するために使用されます。CredentialProvider API は、LDAP バインドパスワードと SSL に必要なパスワードを保護するために使用されます。 LDAP グループマッピング
SSL パスワード FileBasedKeyStoresFactory は、SSL 関連のパスワードを解決するために資格情報プロバイダ API を利用します。 TODO
HDFS DFSUtil は、Configuration.getPassword()を使用して、資格情報プロバイダ API を使用するか、ssl-server.xmlに格納されているクリアテキスト値にフォールバックします。Zookeeper ベースのフェデレーションステートストアとフェールオーバーコントローラーは、Configuration.getPassword を使用して Zookeeper 認証情報を取得し、クリアテキスト認証情報へのフォールバックを提供します。 TODO
YARN WebAppUtils は、Configuration の新しいメソッド getPassword を介して資格情報プロバイダ API の使用を取り込みます。これにより、下位互換性を維持しながら、パスワードを ssl-server.xml ファイル内のクリアテキストで保存する代わりに、代替手段が提供されます。Zookeeper ベースのリソースマネージャステートストアは、Configuration.getPassword を使用して Zookeeper 認証情報を取得し、クリアテキスト認証情報へのフォールバックを提供します。 TODO
KMS HttpServer2.loadSSLConfiguration を使用します。これは Configuration.getPassword を利用して SSL 関連の資格情報を読み取ります。それらは、Credential Provider を介して、または許可されている場合は設定内のクリアテキストから解決される場合があります。 KMS
HttpFS HttpServer2.loadSSLConfiguration を使用します。これは Configuration.getPassword を利用して SSL 関連の資格情報を読み取ります。それらは、Credential Provider を介して、または許可されている場合は設定内のクリアテキストから解決される場合があります。 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
trace.password プロパティは、Tracer が Accumulo で認証し、トレースをトレーステーブルに永続化するために使用されます。資格情報プロバイダ API は、下位互換性のために、プロバイダまたは構成から trace.password を取得するために使用されます。 TODO
Apache
Slider
必要なパスワードをユーザーにプロンプト表示し、CredentialProvider を使用して保存して、後でアプリで取得できるようにする機能が Slider に追加されました。 TODO
Apache
Hive
メタストアパスワード、SSL 関連パスワード、および JDO 文字列パスワードの保護が、Credential Provider API の使用を通じて追加されました。 TODO
Apache
HBase
HBase RESTServer は、新しい Configuration.getPassword メソッドを使用しているため、最初に資格情報プロバイダ API がチェックされ、許可されている場合はクリアテキストにフォールバックします。 TODO
Apache
Oozie
資格情報プロバイダ API を使用して、SSL、電子メール、および JDBC パスワードを保護します。 TODO
Apache
Ranger
資格情報プロバイダ API を使用して、データベース、信頼、キーストアのパスワードを保護します。 TODO

資格情報の管理

hadoop credential コマンド

使用法: hadoop credential <サブコマンド> [オプション]

コマンドオプションの詳細については、コマンドマニュアルを参照してください。

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 キーストアプロバイダーであること、および nn1.example.com/my/path/test.jceks の HDFS 内にあるファイルも Java キーストアプロバイダーのストアであることを示します。

プロバイダーの種類

  1. プロバイダー URI user:/// で表される UserProvider は、ユーザーのクレデンシャルファイルからクレデンシャルを取得するために使用されます。このファイルは、ジョブとアプリケーションの実行に必要なさまざまなトークン、シークレット、パスワードを格納するために使用されます。
  2. プロバイダー URI jceks://SCHEME/path-to-keystore で表される JavaKeyStoreProvider は、ファイルシステム <SCHEME> の Java キーストアファイルからクレデンシャルを取得するために使用されます。Hadoop ファイルシステム API の基礎的な使用により、クレデンシャルをローカルファイルシステムまたはクラスター内ストアに格納できます。
  3. プロバイダー URI localjceks://file/path-to-keystore で表される LocalJavaKeyStoreProvider は、ローカルファイルシステムに格納する必要がある Java キーストアからクレデンシャルにアクセスするために使用されます。これは、HDFS へのアクセスで再帰的な依存関係が生じるクレデンシャルに必要です。HDFS へのアクセスを取得するためにクレデンシャルが必要な場合は常に、そうするために HDFS からクレデンシャルを取得することはできません。
  4. プロバイダー URI bcfks://SCHEME/path-to-keystore で表される BouncyCastleFIPSKeyStoreProvider は、ファイルシステム <SCHEME> の Bouncy Castle FIPS キーストアファイルからクレデンシャルを取得するために使用されます。Hadoop ファイルシステム API の基礎的な使用により、クレデンシャルをローカルファイルシステムまたはクラスター内ストアに格納できます。
  5. プロバイダー URI localbcfks://file/path-to-keystore で表される LocalBcouncyCastleFIPSKeyStoreProvider は、ローカルファイルシステムに格納する必要がある Bouncy Castle FIPS キーストアからクレデンシャルにアクセスするために使用されます。これは、HDFS へのアクセスで再帰的な依存関係が生じるクレデンシャルに必要です。HDFS へのアクセスを取得するためにクレデンシャルが必要な場合は常に、そうするために HDFS からクレデンシャルを取得することはできません。

クレデンシャルがファイルシステムに格納される場合、次のルールが適用されます

  • ローカルの localjceks:// または localbcfks:// ファイルに格納されたクレデンシャルは、構成を読み込むプロセスでロードされます。YARN アプリケーションで使用する場合は、クラスター全体、つまりホストのローカルファイルシステムで表示できる必要があります。

  • jceks:// または bcfks:// プロバイダーで格納されたクレデンシャルは、クラスターファイルシステムに格納でき、クラスター全体で表示できます。ただし、アクセスに特定のクレデンシャルを必要とするファイルシステムでは表示できません。

ファイルシステムの URI を jceks URI でラップするには、次の手順に従ってください。Bouncy Castle FIPS プロバイダーは、jceksbcfks に置き換え、OS/JDK レベルの FIPS プロバイダーが構成されていることを除いて、同様の手順に従います。

  1. hdfs://namenode:9001/users/alice/secrets.jceks などのファイルシステム URI を取得します
  2. URL の先頭に jceks:// を配置します: jceks://hdfs://namenode:9001/users/alice/secrets.jceks
  3. 2 番目の :// 文字列を @ 記号に置き換えます: 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

無限再帰を避けるために、abfss3aadlswasb などのファイルシステムでは、独自のファイルシステムスキームのパスに格納されたキーストアは、検索対象のクレデンシャルとは異なるクレデンシャルのセットを使用するコンテナに格納されている場合でも、明示的に除外されることに注意してください。

例として、s3a://shared/secrets/secret.jceks に格納されたクレデンシャルを使用して、コンテナ s3a://private/ のクレデンシャルを読み取ることはできません。

キーストアのパスワード

Java のキーストアは通常、パスワードで保護されています。キーストアベースのクレデンシャルプロバイダーの主な保護方法は、OS レベルのファイルアクセス許可と、ターゲットファイルシステムに存在する可能性のあるその他のポリシーベースのアクセス保護です。パスワードは主な保護ソースではありませんが、これらのパスワードを管理するために必要なメカニズムと使用可能なオプションを理解することは非常に重要です。また、実行時にキーストアを消費するために、キーストアを保護するために使用されるパスワードにアクセスする必要があるすべての関係者を理解することも非常に重要です。

オプション
オプション 説明
デフォルトのパスワード これは「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 環境変数は、キーストアベースのクレデンシャルプロバイダーからクレデンシャルにアクセスする必要があるプロセスのプロバイダーパスで構成されている可能性のあるすべてのキーストアのカスタムパスワードに設定する必要があります。コンマ区切りのプロバイダーのパス全体に対して、環境変数は 1 つしかありません。各キーストアに必要なパスワードを知ることは難しいため、この問題を回避するために、すべてのキーストアベースのクレデンシャルプロバイダーに同じパスワードを使用することをお勧めします。環境変数を設定するには、スクリプトまたはその他のクリアテキストストレージメカニズムから設定する必要がある可能性があります。実行中のプロセスの環境変数は、さまざまな unix コマンドから利用できます。 はい はい いいえ
パスワードファイル hadoop.security.credstore.java-keystore-provider.password-file 構成プロパティは、プロバイダーパスで構成されている可能性のあるすべてのキーストアのカスタムパスワードを含む「サイドファイル」の場所に設定する必要があります。キーストアベースのクレデンシャルプロバイダーからクレデンシャルにアクセスする必要があるプロセスは、この構成プロパティを適切なファイルロケーションに設定する必要があります。コンマ区切りのプロバイダーのパス全体に対して、パスワードファイルは 1 つしかありません。各キーストアに必要なパスワードを知ることは難しいため、この問題を回避するために、すべてのキーストアベースのクレデンシャルプロバイダーに同じパスワードを使用することをお勧めします。パスワードファイルは、管理する必要がある追加のファイルであり、パスワードをクリアテキストで格納し、アクセスする必要があるユーザーだけがアクセスできるようにファイルアクセス許可を設定する必要があります。ファイルアクセス許可が不適切に設定されている場合、キーストアにアクセスするためのパスワードはクリアテキストで利用できます。 はい はい はい

デフォルトのパスワードを使用するということは、ランタイムコンシューマーへの追加の通信/同期を行う必要がないことを意味します。デフォルトのパスワードはわかっていますが、ファイルアクセス許可がキーストアの主な保護手段です。

ファイルアクセス許可が妨害された場合、「サイドファイル」とは異なり、既知のパスワードがあっても保護されたクレデンシャルを公開できる標準ツールはありません。Keytool では、6 文字以上のパスワードが必要であり、キーストアから一般的なシークレットを取得する方法がわかりません。また、PKI キーペアに限定されています。エディターはキーストアに格納されたシークレットを明らかにせず、catmore、またはその他の標準ツールも同様です。これが、キーストアプロバイダーがクレデンシャルの「サイドファイル」ストレージよりも優れている理由です。

とは言え、APIを利用してキーストアベースの認証情報プロバイダー内に保存された認証情報にアクセスするコードを誰かが記述することは容易です。繰り返しになりますが、デフォルトのパスワードを使用する場合、パスワードは単にキーストアを永続化するための形式に過ぎません。唯一の保護は、ファイルパーミッションとOSレベルのアクセス制御ポリシーです。

ユーザーは、キーストア自体のパスワードを保存するために、パスワード「サイドファイル」を使用することを選択する場合があります。これはサポートされています。このレベルの正確性を実現するために必要なメカニズムを認識することが非常に重要です。

プレーンテキストへのフォールバックの無効化

Credentials.getPassword()操作は、認証情報プロバイダーが存在しない場合、またはキーが見つからない場合、設定XMLファイルのエントリを使用するようにフォールバックします。

この動作は、設定オプションhadoop.security.credential.clear-text-fallbacktrueから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経由で検索されるすべての設定オプションは、認証情報プロバイダーを通じて提供される必要があります