Hadoop Key Management Server (KMS) - ドキュメントセット

Hadoop KMSは、HadoopのKeyProvider APIに基づく暗号化キー管理サーバーです。

これは、REST APIを使用してHTTP経由で通信するクライアントコンポーネントとサーバーコンポーネントを提供します。

クライアントは、KMS HTTP REST APIを使用してKMSと対話するKeyProvider実装です。

KMSとそのクライアントは、組み込みのセキュリティを備えており、HTTP SPNEGO Kerberos認証とHTTPSセキュアトランスポートをサポートしています。

KMSはJava Jetty Webアプリケーションです。

KMSクライアント構成

KMSクライアントのKeyProviderkmsスキームを使用し、埋め込まれたURLはKMSのURLである必要があります。たとえば、https://127.0.0.1:9600/kmsで実行されているKMSの場合、KeyProvider URIはkms://http@localhost:9600/kmsです。また、https://127.0.0.1:9600/kmsで実行されているKMSの場合、KeyProvider URIはkms://https@localhost:9600/kmsです。

以下は、HDFS NameNodeをcore-site.xmlでKMSクライアントとして構成する例です。

<property>
  <name>hadoop.security.key.provider.path</name>
  <value>kms://http@localhost:9600/kms</value>
  <description>
    The KeyProvider to use when interacting with encryption keys used
    when reading and writing to an encryption zone.
  </description>
</property>

KMS

KMSの起動/停止

KMSを起動/停止するには、hadoop --daemon start|stop kmsを使用します。例:

hadoop-3.3.6 $ hadoop --daemon start kms

注:スクリプトkms.shは非推奨になりました。これは現在、hadoop kmsのラッパーにすぎません。

KMS構成

etc/hadoop/kms-site.xml構成ファイルで、KMSのバックアップKeyProviderプロパティを構成します

  <property>
     <name>hadoop.kms.key.provider.uri</name>
     <value>jceks://file@/${user.home}/kms.keystore</value>
  </property>

  <property>
    <name>hadoop.security.keystore.java-keystore-provider.password-file</name>
    <value>kms.keystore.password</value>
  </property>

パスワードファイルは、クラスパスを介してHadoopの構成ディレクトリで検索されます。

注:構成の変更を有効にするには、KMSを再起動する必要があります。

注:KMSサーバーは、バックアッププロバイダーとして任意のKeyProvider実装を選択できます。ここでの例では、JavaKeyStoreProviderを使用していますが、これは実験目的でのみ使用する必要があり、実稼働環境では絶対に使用しないでください。JavaKeyStoreProviderの詳細な使用法と注意事項については、資格情報プロバイダーAPIのキーストアパスワードセクションを参照してください。

KMS HTTP構成

KMSは、HTTPポートを9600に事前構成します。

KMSは、etc/hadoop/kms-site.xmlで、次のHTTP 構成プロパティをサポートしています。

注:構成の変更を有効にするには、KMSを再起動する必要があります。

KMSキャッシュ

KMSには、暗号化キーをキャッシュするためのCachingKeyProviderと、EEKをキャッシュするためのKeyProviderという2種類のキャッシュがあります。

CachingKeyProvider

KMSは、基になるKeyProviderへの過度のヒットを避けるために、暗号化キーを短期間キャッシュします。

このキャッシュはデフォルトで有効になっています(hadoop.kms.cache.enableブールプロパティをfalseに設定することで無効にできます)。

このキャッシュは、次の3つのメソッドgetCurrentKey()getKeyVersion()、およびgetMetadata()でのみ使用されます。

getCurrentKey()メソッドの場合、キャッシュされたエントリは、キーがアクセスされる回数に関係なく、最大30000ミリ秒間保持されます(古いキーが現在のキーと見なされるのを避けるため)。

getKeyVersion()およびgetMetadata()メソッドの場合、キャッシュされたエントリは、デフォルトの非アクティブタイムアウトである600000ミリ秒(10分)で保持されます。

キャッシュは、deleteKey()によってキーが削除された場合、またはinvalidateCache()が呼び出された場合に無効になります。

これらの構成は、etc/hadoop/kms-site.xml構成ファイルで次のプロパティを使用して変更できます。

   <property>
     <name>hadoop.kms.cache.enable</name>
     <value>true</value>
   </property>

   <property>
     <name>hadoop.kms.cache.timeout.ms</name>
     <value>600000</value>
   </property>

   <property>
     <name>hadoop.kms.current.key.cache.timeout.ms</name>
     <value>30000</value>
   </property>

KeyProvider

アーキテクチャ上、サーバー側(例:KMS)とクライアント側(例:NameNode)の両方に、EEKのキャッシュがあります。以下は、キャッシュで構成可能です。

  • キャッシュのサイズ。これは、各キー名の下でキャッシュできるEEKの最大数です。
  • キャッシュの低水位標。各キー名について、get呼び出し後に、キャッシュされたEEKの数が(サイズ*低水位標)より少ない場合、このキー名のキャッシュは非同期的に入力されます。各キー名について、非同期入力のために実行できるスレッドは1つだけです。
  • キャッシュ内のキューを埋めることを許可されている、キー名全体にわたる非同期スレッドの最大数。
  • キャッシュの有効期限(ミリ秒単位)。内部的には、Guavaキャッシュがキャッシュ実装として使用されます。有効期限のアプローチはexpireAfterAccessです。

非同期入力メカニズムのため、rollNewVersion()の後に、呼び出し元が古いEEKを取得する可能性があることに注意してください。最悪の場合、呼び出し元は、(サーバー側のキャッシュサイズ+クライアント側のキャッシュサイズ)までの数の古いEEKを取得するか、両方のキャッシュが期限切れになるまで取得する可能性があります。この動作は、キャッシュでのロックを回避するためのトレードオフであり、古いバージョンのEEKは復号化にも使用できるため、許容されます。

以下は構成とそのデフォルト値です。

サーバー側は、etc/hadoop/kms-site.xml構成ファイルで次のプロパティを使用して変更できます。

   <property>
     <name>hadoop.security.kms.encrypted.key.cache.size</name>
     <value>500</value>
   </property>

   <property>
     <name>hadoop.security.kms.encrypted.key.cache.low.watermark</name>
     <value>0.3</value>
   </property>

   <property>
     <name>hadoop.security.kms.encrypted.key.cache.num.fill.threads</name>
     <value>2</value>
   </property>

   <property>
     <name>hadoop.security.kms.encrypted.key.cache.expiry</name>
     <value>43200000</value>
   </property>

クライアント側は、etc/hadoop/core-site.xml構成ファイルで次のプロパティを使用して変更できます。

   <property>
     <name>hadoop.security.kms.client.encrypted.key.cache.size</name>
     <value>500</value>
   </property>

   <property>
     <name>hadoop.security.kms.client.encrypted.key.cache.low-watermark</name>
     <value>0.3</value>
   </property>

   <property>
     <name>hadoop.security.kms.client.encrypted.key.cache.num.refill.threads</name>
     <value>2</value>
   </property>

   <property>
     <name>hadoop.security.kms.client.encrypted.key.cache.expiry</name>
     <value>43200000</value>
   </property>

KMS集計監査ログ

監査ログは、GET_KEY_VERSION、GET_CURRENT_KEY、DECRYPT_EEK、GENERATE_EEK、REENCRYPT_EEK操作へのAPIアクセスに対して集計されます。

エントリは、(ユーザー、キー、操作)の結合キーでグループ化され、構成可能な集計間隔後に、特定のキーに対してユーザーが指定したエンドポイントにアクセスした回数が監査ログにフラッシュされます。

集計間隔は、プロパティを使用して構成されます

  <property>
    <name>hadoop.kms.aggregation.delay.ms</name>
    <value>10000</value>
  </property>

KMSセキュリティ構成

Kerberos HTTP SPNEGO認証の有効化

KDCサーバーの情報を使用して、Kerberos etc/krb5.confファイルを構成します。

KMSのサービスプリンシパルとそのkeytabを作成します。これはHTTPサービスプリンシパルである必要があります。

正しいセキュリティ値を使用して、KMS etc/hadoop/kms-site.xmlを構成します。例:

   <property>
     <name>hadoop.kms.authentication.type</name>
     <value>kerberos</value>
   </property>

   <property>
     <name>hadoop.kms.authentication.kerberos.keytab</name>
     <value>${user.home}/kms.keytab</value>
   </property>

   <property>
     <name>hadoop.kms.authentication.kerberos.principal</name>
     <value>HTTP/localhost</value>
   </property>

   <property>
     <name>hadoop.kms.authentication.kerberos.name.rules</name>
     <value>DEFAULT</value>
   </property>

注:構成の変更を有効にするには、KMSを再起動する必要があります。

KMSプロキシユーザー構成

各プロキシユーザーは、次のプロパティを使用してetc/hadoop/kms-site.xmlで構成する必要があります。

  <property>
    <name>hadoop.kms.proxyuser.#USER#.users</name>
    <value>*</value>
  </property>

  <property>
    <name>hadoop.kms.proxyuser.#USER#.groups</name>
    <value>*</value>
  </property>

  <property>
    <name>hadoop.kms.proxyuser.#USER#.hosts</name>
    <value>*</value>
  </property>

#USER#は、構成するプロキシユーザーのユーザー名です。

usersプロパティは、偽装できるユーザーを示します。

groupsプロパティは、偽装されるユーザーが属する必要のあるグループを示します。

usersプロパティまたはgroupsプロパティの少なくとも1つを定義する必要があります。両方が指定されている場合、構成されたプロキシユーザーは、usersリスト内のユーザーと、groupsリスト内のグループのいずれかに属する任意のユーザーを偽装できます。

hostsプロパティは、プロキシユーザーが偽装要求を行うことができるホストを示します。

usersgroups、またはhosts*がある場合、ユーザー、グループ、またはホストに関してプロキシユーザーに制限がないことを意味します。

HTTPS (SSL) を介した KMS

etc/hadoop/kms-site.xmlでSSLを有効にします。

  <property>
    <name>hadoop.kms.ssl.enabled</name>
    <value>true</value>
    <description>
      Whether SSL is enabled. Default is false, i.e. disabled.
    </description>
  </property>

適切な値を使用してetc/hadoop/ssl-server.xmlを構成します。例:

<property>
  <name>ssl.server.keystore.location</name>
  <value>${user.home}/.keystore</value>
  <description>Keystore to be used. Must be specified.</description>
</property>

<property>
  <name>ssl.server.keystore.password</name>
  <value></value>
  <description>Must be specified.</description>
</property>

<property>
  <name>ssl.server.keystore.keypassword</name>
  <value></value>
  <description>Must be specified.</description>
</property>

SSLパスワードは、資格情報プロバイダーで保護できます。資格情報プロバイダーAPIを参照してください。

KMS用のSSL証明書を作成する必要があります。kms Unixユーザーとして、Javaのkeytoolコマンドを使用してSSL証明書を作成してください。

$ keytool -genkey -alias jetty -keyalg RSA

インタラクティブなプロンプトで一連の質問がされます。これにより、キーストアファイルが作成されます。ファイル名は.keystoreで、ユーザーのホームディレクトリに配置されます。

「キーストアパスワード」に入力するパスワードは、構成ディレクトリのssl-server.xmlで設定されたプロパティssl.server.keystore.passwordの値と一致する必要があります。

「あなたの氏名は何ですか?」(つまり「CN」)に対する回答は、KMSが実行されるマシンのホスト名である必要があります。

注:構成の変更を有効にするには、KMSを再起動する必要があります。

注意: 一部の古いSSLクライアントは、KMSサーバーでサポートされていない脆弱な暗号を使用する可能性があります。SSLクライアントをアップグレードすることをお勧めします。

ACL(アクセス制御リスト)

KMSは、きめ細かい権限制御のためにACL(アクセス制御リスト)をサポートしています。

KMSには、KMS ACLとキーACLの2つのレベルのACLが存在します。KMS ACLはKMS操作レベルでのアクセスを制御し、キーACLよりも優先されます。特に、KMS ACLレベルで権限が付与されている場合にのみ、キーACLに対する権限チェックが実行されます。

KMS ACLとキーACLの設定と使用法については、以下のセクションで説明します。

KMS ACL

KMS ACLの設定は、KMSのetc/hadoop/kms-acls.xml設定ファイルで定義されます。このファイルは、変更されるとホットリロードされます。

KMSは、一連のACL構成プロパティを介して、きめ細かいアクセス制御とKMS操作のブラックリストの両方をサポートします。

KMSにアクセスするユーザーは、まず要求された操作のアクセス制御リストに含まれているかどうかがチェックされ、次にアクセスが許可される前に、操作のブラックリストで除外されているかどうかがチェックされます。

<configuration>
  <property>
    <name>hadoop.kms.acl.CREATE</name>
    <value>*</value>
    <description>
          ACL for create-key operations.
          If the user is not in the GET ACL, the key material is not returned
          as part of the response.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.CREATE</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for create-key operations.
          If the user is in the Blacklist, the key material is not returned
          as part of the response.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.DELETE</name>
    <value>*</value>
    <description>
          ACL for delete-key operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.DELETE</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for delete-key operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.ROLLOVER</name>
    <value>*</value>
    <description>
          ACL for rollover-key operations.
          If the user is not in the GET ACL, the key material is not returned
          as part of the response.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.ROLLOVER</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for rollover-key operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.GET</name>
    <value>*</value>
    <description>
          ACL for get-key-version and get-current-key operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.GET</name>
    <value>hdfs,foo</value>
    <description>
          ACL for get-key-version and get-current-key operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.GET_KEYS</name>
    <value>*</value>
    <description>
         ACL for get-keys operation.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.GET_KEYS</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for get-keys operation.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.GET_METADATA</name>
    <value>*</value>
    <description>
        ACL for get-key-metadata and get-keys-metadata operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.GET_METADATA</name>
    <value>hdfs,foo</value>
    <description>
         Blacklist for get-key-metadata and get-keys-metadata operations.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.SET_KEY_MATERIAL</name>
    <value>*</value>
    <description>
            Complimentary ACL for CREATE and ROLLOVER operation to allow the client
            to provide the key material when creating or rolling a key.
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.SET_KEY_MATERIAL</name>
    <value>hdfs,foo</value>
    <description>
            Complimentary Blacklist for CREATE and ROLLOVER operation to allow the client
            to provide the key material when creating or rolling a key.
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.GENERATE_EEK</name>
    <value>*</value>
    <description>
          ACL for generateEncryptedKey
          CryptoExtension operations
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.GENERATE_EEK</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for generateEncryptedKey
          CryptoExtension operations
    </description>
  </property>

  <property>
    <name>hadoop.kms.acl.DECRYPT_EEK</name>
    <value>*</value>
    <description>
          ACL for decrypt EncryptedKey
          CryptoExtension operations
    </description>
  </property>

  <property>
    <name>hadoop.kms.blacklist.DECRYPT_EEK</name>
    <value>hdfs,foo</value>
    <description>
          Blacklist for decrypt EncryptedKey
          CryptoExtension operations
    </description>
  </property>
</configuration>
キーACL

KMSは、キーレベルでのすべての読み取り以外の操作に対するアクセス制御をサポートしています。すべてのキーアクセス操作は、次のように分類されます。

  • MANAGEMENT - createKey、deleteKey、rolloverNewVersion
  • GENERATE_EEK - generateEncryptedKey、reencryptEncryptedKey、reencryptEncryptedKeys、warmUpEncryptedKeys
  • DECRYPT_EEK - decryptEncryptedKey
  • READ - getKeyVersion、getKeyVersions、getMetadata、getKeysMetadata、getCurrentKey
  • ALL - 上記すべて

これらは、KMSのetc/hadoop/kms-acls.xmlで次のように定義できます。

キーアクセスが明示的に構成されていないすべてのキーについて、操作タイプの一部についてデフォルトのキーアクセス制御を構成できます。

また、操作タイプの一部について「ホワイトリスト」キーACLを構成することもできます。ホワイトリストキーACLは、明示的またはデフォルトのキーごとのACLに加えて、キーへのアクセスを許可します。つまり、キーごとのACLが明示的に設定されていない場合、ユーザーがデフォルトのキーごとのACLまたはホワイトリストキーACLに存在する場合、アクセスが許可されます。キーごとのACLが明示的に設定されている場合、ユーザーがキーごとのACLまたはホワイトリストキーACLに存在する場合、アクセスが許可されます。

特定のキーに対してACLが構成されておらず、デフォルトのACLが構成されておらず、要求された操作に対してホワイトリストキーACLが構成されていない場合、アクセスは拒否されます。

注意: デフォルトおよびホワイトリストキーACLは、ALL操作修飾子をサポートしていません。

  <property>
    <name>key.acl.testKey1.MANAGEMENT</name>
    <value>*</value>
    <description>
      ACL for create-key, deleteKey and rolloverNewVersion operations.
    </description>
  </property>

  <property>
    <name>key.acl.testKey2.GENERATE_EEK</name>
    <value>*</value>
    <description>
      ACL for generateEncryptedKey operations.
    </description>
  </property>

  <property>
    <name>key.acl.testKey3.DECRYPT_EEK</name>
    <value>admink3</value>
    <description>
      ACL for decryptEncryptedKey operations.
    </description>
  </property>

  <property>
    <name>key.acl.testKey4.READ</name>
    <value>*</value>
    <description>
      ACL for getKeyVersion, getKeyVersions, getMetadata, getKeysMetadata,
      getCurrentKey operations
    </description>
  </property>

  <property>
    <name>key.acl.testKey5.ALL</name>
    <value>*</value>
    <description>
      ACL for ALL operations.
    </description>
  </property>

  <property>
    <name>whitelist.key.acl.MANAGEMENT</name>
    <value>admin1</value>
    <description>
      whitelist ACL for MANAGEMENT operations for all keys.
    </description>
  </property>

  <!--
  'testKey3' key ACL is defined. Since a 'whitelist'
  key is also defined for DECRYPT_EEK, in addition to
  admink3, admin1 can also perform DECRYPT_EEK operations
  on 'testKey3'
-->
  <property>
    <name>whitelist.key.acl.DECRYPT_EEK</name>
    <value>admin1</value>
    <description>
      whitelist ACL for DECRYPT_EEK operations for all keys.
    </description>
  </property>

  <property>
    <name>default.key.acl.MANAGEMENT</name>
    <value>user1,user2</value>
    <description>
      default ACL for MANAGEMENT operations for all keys that are not
      explicitly defined.
    </description>
  </property>

  <property>
    <name>default.key.acl.GENERATE_EEK</name>
    <value>user1,user2</value>
    <description>
      default ACL for GENERATE_EEK operations for all keys that are not
      explicitly defined.
    </description>
  </property>

  <property>
    <name>default.key.acl.DECRYPT_EEK</name>
    <value>user1,user2</value>
    <description>
      default ACL for DECRYPT_EEK operations for all keys that are not
      explicitly defined.
    </description>
  </property>

  <property>
    <name>default.key.acl.READ</name>
    <value>user1,user2</value>
    <description>
      default ACL for READ operations for all keys that are not
      explicitly defined.
    </description>
  </property>

KMS委任トークン構成

KMSは、Kerberos認証情報を持たないプロセスからキープロバイダーへの認証に委任トークンをサポートしています。

KMS委任トークン認証は、デフォルトのHadoop認証を拡張します。Hadoop認証と同様に、KMS委任トークンは委任トークン認証を使用してフェッチまたは更新しないでください。詳細については、Hadoop Authページを参照してください。

さらに、KMS委任トークンシークレットマネージャーは、次のプロパティで構成できます。

  <property>
    <name>hadoop.kms.authentication.delegation-token.update-interval.sec</name>
    <value>86400</value>
    <description>
      How often the master key is rotated, in seconds. Default value 1 day.
    </description>
  </property>

  <property>
    <name>hadoop.kms.authentication.delegation-token.max-lifetime.sec</name>
    <value>604800</value>
    <description>
      Maximum lifetime of a delegation token, in seconds. Default value 7 days.
    </description>
  </property>

  <property>
    <name>hadoop.kms.authentication.delegation-token.renew-interval.sec</name>
    <value>86400</value>
    <description>
      Renewal interval of a delegation token, in seconds. Default value 1 day.
    </description>
  </property>

  <property>
    <name>hadoop.kms.authentication.delegation-token.removal-scan-interval.sec</name>
    <value>3600</value>
    <description>
      Scan interval to remove expired delegation tokens.
    </description>
  </property>

高可用性

複数のKMSインスタンスを使用して、高可用性とスケーラビリティを提供できます。現在、複数のKMSインスタンスをサポートするには、ロードバランサー/VIPの背後でKMSインスタンスを実行するか、LoadBalancingKMSClientProviderを使用するという2つのアプローチがあります。

どちらのアプローチでも、同じクライアントからのリクエストが異なるKMSインスタンスによって処理される可能性があるため、KMSインスタンスは単一の論理サービスとして正しく機能するように特別に構成する必要があります。特に、Kerberosプリンシパル構成、HTTP認証署名、および委任トークンは特別な注意が必要です。

ロードバランサーまたはVIPの背後

KMSクライアントとサーバーはHTTPを介してREST APIを介して通信するため、ロードバランサーまたはVIPを使用して、スケーラビリティとHAを実現するために着信トラフィックを分散できます。このモードでは、クライアントはサーバー側の複数のKMSインスタンスを認識しません。

LoadBalancingKMSClientProviderの使用

ロードバランサーまたはVIPの背後で複数のKMSインスタンスを実行する代わりに、LoadBalancingKMSClientProviderを使用することもできます。このアプローチを使用すると、KMSクライアント(たとえば、HDFS NameNode)は複数のKMSインスタンスを認識し、それらにラウンドロビン方式でリクエストを送信します。LoadBalancingKMSClientProviderは、hadoop.security.key.provider.pathで複数のURIが指定されている場合に暗黙的に使用されます。

core-site.xmlの次の例では、2つのKMSインスタンスkms01.example.comkms02.example.comを構成しています。ホスト名はセミコロンで区切られており、すべてのKMSインスタンスは同じポートで実行する必要があります。

<property>
  <name>hadoop.security.key.provider.path</name>
  <value>kms://https@kms01.example.com;kms02.example.com:9600/kms</value>
  <description>
    The KeyProvider to use when interacting with encryption keys used
    when reading and writing to an encryption zone.
  </description>
</property>

KMSインスタンスへのリクエストが失敗した場合、クライアントは次のインスタンスで再試行します。すべてのインスタンスが失敗した場合にのみ、リクエストは失敗として返されます。

HTTP Kerberosプリンシパル構成

KMSインスタンスがロードバランサーまたはVIPの背後にある場合、クライアントはVIPのホスト名を使用します。Kerberos SPNEGO認証の場合、URLのホスト名は、サーバーのKerberosサービス名HTTP/#HOSTNAME#を構築するために使用されます。つまり、すべてのKMSインスタンスは、ロードバランサーまたはVIPのホスト名を持つKerberosサービス名を持っている必要があります。

特定のKMSインスタンスに直接アクセスできるようにするために、KMSインスタンスは独自のホスト名を持つKerberosサービス名も持つ必要があります。これは、監視および管理の目的で必要です。

(ロードバランサー/VIPホスト名および実際のKMSインスタンスホスト名に対する)両方のKerberosサービスプリンシパル認証情報は、認証用に構成されたkeytabファイルにある必要があります。そして、構成で指定されたプリンシパル名は「*」である必要があります。例:

  <property>
    <name>hadoop.kms.authentication.kerberos.principal</name>
    <value>*</value>
  </property>

注意: HTTPSを使用している場合、KMSインスタンスで使用されるSSL証明書は、複数のホスト名をサポートするように構成する必要があります(これを行う方法の詳細については、Java 7のkeytoolSAN拡張サポートを参照してください)。

HTTP認証署名

KMSは、HTTP認証にHadoop認証を使用します。Hadoop認証は、クライアントが正常に認証されたら、署名付きのHTTP Cookieを発行します。このHTTP Cookieには有効期限があり、それを過ぎると新しい認証シーケンスがトリガーされます。これは、クライアントのすべてのHTTPリクエストで認証をトリガーしないようにするためです。

KMSインスタンスは、他のKMSインスタンスによって署名されたHTTP Cookie署名を確認する必要があります。これを行うために、すべてのKMSインスタンスが署名シークレットを共有する必要があります。詳細な説明と構成例については、SignerSecretProvider構成を参照してください。KMS構成には、以下の例に示すように、hadoop.kms.authenticationというプレフィックスを付ける必要があることに注意してください。

このシークレット共有は、kms-site.xmlの次のプロパティを使用してKMSで構成されたZookeeperサービスを使用して行うことができます。

  <property>
    <name>hadoop.kms.authentication.signer.secret.provider</name>
    <value>zookeeper</value>
    <description>
      Indicates how the secret to sign the authentication cookies will be
      stored. Options are 'random' (default), 'file' and 'zookeeper'.
      If using a setup with multiple KMS instances, 'zookeeper' should be used.
      If using file, signature.secret.file should be configured and point to the secret file.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.signer.secret.provider.zookeeper.path</name>
    <value>/hadoop-kms/hadoop-auth-signature-secret</value>
    <description>
      The Zookeeper ZNode path where the KMS instances will store and retrieve
      the secret from. All KMS instances that need to coordinate should point to the same path.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.signer.secret.provider.zookeeper.connection.string</name>
    <value>#HOSTNAME#:#PORT#,...</value>
    <description>
      The Zookeeper connection string, a list of hostnames and port comma
      separated.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.signer.secret.provider.zookeeper.auth.type</name>
    <value>sasl</value>
    <description>
      The Zookeeper authentication type, 'none' (default) or 'sasl' (Kerberos).
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.signer.secret.provider.zookeeper.kerberos.keytab</name>
    <value>/etc/hadoop/conf/kms.keytab</value>
    <description>
      The absolute path for the Kerberos keytab with the credentials to
      connect to Zookeeper.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.signer.secret.provider.zookeeper.kerberos.principal</name>
    <value>kms/#HOSTNAME#</value>
    <description>
      The Kerberos service principal used to connect to Zookeeper.
    </description>
  </property>

委任トークン

HTTP認証と同様に、KMSは委任トークンにもHadoop認証を使用します。HA環境下では、すべてのKMSインスタンスは、別のKMSインスタンスによって発行された委任トークンを確認する必要があります。これを行うために、すべてのKMSインスタンスはZKDelegationTokenSecretManagerを使用して、ZooKeeperからTokenIdentifiersとDelegationKeysを取得する必要があります。

etc/hadoop/kms-site.xmlの構成例

  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.enable</name>
    <value>true</value>
    <description>
      If true, Hadoop KMS uses ZKDelegationTokenSecretManager to persist
      TokenIdentifiers and DelegationKeys in ZooKeeper.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.zkConnectionString</name>
    <value>#HOSTNAME#:#PORT#,...</value>
    <description>
      The ZooKeeper connection string, a comma-separated list of hostnames and port.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.znodeWorkingPath</name>
    <value>/hadoop-kms/zkdtsm</value>
    <description>
      The ZooKeeper znode path where the KMS instances will store and retrieve
      the secret from. All the KMS instances that need to coordinate should point to the same path.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.zkAuthType</name>
    <value>sasl</value>
    <description>
      The ZooKeeper authentication type, 'none' (default) or 'sasl' (Kerberos).
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.kerberos.keytab</name>
    <value>/etc/hadoop/conf/kms.keytab</value>
    <description>
      The absolute path for the Kerberos keytab with the credentials to
      connect to ZooKeeper. This parameter is effective only when
      hadoop.kms.authentication.zk-dt-secret-manager.zkAuthType is set to 'sasl'.
    </description>
  </property>
  <property>
    <name>hadoop.kms.authentication.zk-dt-secret-manager.kerberos.principal</name>
    <value>kms/#HOSTNAME#</value>
    <description>
      The Kerberos service principal used to connect to ZooKeeper.
      This parameter is effective only when
      hadoop.kms.authentication.zk-dt-secret-manager.zkAuthType is set to 'sasl'.
    </description>
  </property>

KMS HTTP REST API

キーの作成

リクエスト

POST http://HOST:PORT/kms/v1/keys
Content-Type: application/json

{
  "name"        : "<key-name>",
  "cipher"      : "<cipher>",
  "length"      : <length>,        //int
  "material"    : "<material>",    //base64
  "description" : "<description>"
}

レスポンス

201 CREATED
LOCATION: http://HOST:PORT/kms/v1/key/<key-name>
Content-Type: application/json

{
  "name"        : "versionName",
  "material"    : "<material>",    //base64, not present without GET ACL
}

キーのロールオーバー

リクエスト

POST http://HOST:PORT/kms/v1/key/<key-name>
Content-Type: application/json

{
  "material"    : "<material>",
}

レスポンス

200 OK
Content-Type: application/json

{
  "name"        : "versionName",
  "material"    : "<material>",    //base64, not present without GET ACL
}

キーのキャッシュの無効化

リクエスト

POST http://HOST:PORT/kms/v1/key/<key-name>/_invalidatecache

レスポンス

200 OK

キーの削除

リクエスト

DELETE http://HOST:PORT/kms/v1/key/<key-name>

レスポンス

200 OK

キーメタデータの取得

リクエスト

GET http://HOST:PORT/kms/v1/key/<key-name>/_metadata

レスポンス

200 OK
Content-Type: application/json

{
  "name"        : "<key-name>",
  "cipher"      : "<cipher>",
  "length"      : <length>,        //int
  "description" : "<description>",
  "created"     : <millis-epoc>,   //long
  "versions"    : <versions>       //int
}

現在のキーの取得

リクエスト

GET http://HOST:PORT/kms/v1/key/<key-name>/_currentversion

レスポンス

200 OK
Content-Type: application/json

{
  "name"        : "versionName",
  "material"    : "<material>",    //base64
}

現在のキーバージョンに対する暗号化されたキーの生成

リクエスト

GET http://HOST:PORT/kms/v1/key/<key-name>/_eek?eek_op=generate&num_keys=<number-of-keys-to-generate>

レスポンス

200 OK
Content-Type: application/json
[
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",          //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",          //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  ...
]

暗号化されたキーの復号化

リクエスト

POST http://HOST:PORT/kms/v1/keyversion/<version-name>/_eek?eek_op=decrypt
Content-Type: application/json

{
  "name"        : "<key-name>",
  "iv"          : "<iv>",          //base64
  "material"    : "<material>",    //base64
}

レスポンス

200 OK
Content-Type: application/json

{
  "name"        : "EK",
  "material"    : "<material>",    //base64
}

最新のキーバージョンで暗号化されたキーの再暗号化

このコマンドは、以前に生成された暗号化されたキーを取得し、KeyProviderの最新のKeyVersion暗号化キーを使用して再暗号化します。最新のKeyVersionが暗号化されたキーの生成に使用されたものと同じ場合、同じ暗号化されたキーが返されます。

これは通常、暗号化キーのロールオーバー後に役立ちます。暗号化されたキーを再暗号化すると、キーマテリアルと初期化ベクトルは同じままですが、最新バージョンの暗号化キーを使用して暗号化できます。

リクエスト

POST http://HOST:PORT/kms/v1/keyversion/<version-name>/_eek?eek_op=reencrypt
Content-Type: application/json

{
  "name"        : "<key-name>",
  "iv"          : "<iv>",          //base64
  "material"    : "<material>",    //base64
}

レスポンス

200 OK
Content-Type: application/json

{
  "versionName"         : "<encryptionVersionName>",
  "iv"                  : "<iv>",            //base64
  "encryptedKeyVersion" : {
      "versionName"       : "EEK",
      "material"          : "<material>",    //base64
  }
}

最新のキーバージョンで暗号化されたキーのバッチ再暗号化

上記の暗号化されたキーの再暗号化のバッチバージョン。このコマンドは、以前に生成された暗号化されたキーのリストを取得し、KeyProviderの最新のKeyVersion暗号化キーを使用して再暗号化し、再暗号化された暗号化されたキーを同じ順序で返します。暗号化されたキーごとに、最新のKeyVersionが暗号化されたキーの生成に使用されたものと同じである場合、アクションは実行されず、同じ暗号化されたキーが返されます。

これは通常、暗号化キーのロールオーバー後に役立ちます。暗号化されたキーを再暗号化すると、キーマテリアルと初期化ベクトルは同じままですが、最新バージョンの暗号化キーを使用して暗号化できます。

バッチリクエストのすべての暗号化キーは、同じ暗号化キー名の下にある必要がありますが、暗号化キーの異なるバージョンにある可能性があります。

リクエスト

POST http://HOST:PORT/kms/v1/key/<key-name>/_reencryptbatch
Content-Type: application/json

[
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",            //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",            //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  ...
]

レスポンス

200 OK
Content-Type: application/json

[
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",            //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  {
    "versionName"         : "<encryptionVersionName>",
    "iv"                  : "<iv>",            //base64
    "encryptedKeyVersion" : {
        "versionName"       : "EEK",
        "material"          : "<material>",    //base64
    }
  },
  ...
]

キーバージョンの取得

リクエスト

GET http://HOST:PORT/kms/v1/keyversion/<version-name>

レスポンス

200 OK
Content-Type: application/json

{
  "name"        : "<name>",
  "versionName" : "<version>",
  "material"    : "<material>",    //base64
}

キーバージョンの取得

リクエスト

GET http://HOST:PORT/kms/v1/key/<key-name>/_versions

レスポンス

200 OK
Content-Type: application/json

[
  {
    "name"        : "<name>",
    "versionName" : "<version>",
    "material"    : "<material>",    //base64
  },
  {
    "name"        : "<name>",
    "versionName" : "<version>",
    "material"    : "<material>",    //base64
  },
  ...
]

キー名の取得

リクエスト

GET http://HOST:PORT/kms/v1/keys/names

レスポンス

200 OK
Content-Type: application/json

[
  "<key-name>",
  "<key-name>",
  ...
]

キーメタデータの取得

GET http://HOST:PORT/kms/v1/keys/metadata?key=<key-name>&key=<key-name>,...

レスポンス

200 OK
Content-Type: application/json

[
  {
    "name"        : "<key-name>",
    "cipher"      : "<cipher>",
    "length"      : <length>,        //int
    "description" : "<description>",
    "created"     : <millis-epoc>,   //long
    "versions"    : <versions>       //int
  },
  {
    "name"        : "<key-name>",
    "cipher"      : "<cipher>",
    "length"      : <length>,        //int
    "description" : "<description>",
    "created"     : <millis-epoc>,   //long
    "versions"    : <versions>       //int
  },
  ...
]

非推奨の環境変数

次の環境変数は非推奨になりました。代わりに、対応する構成プロパティを設定してください。

環境変数 構成プロパティ 構成ファイル
KMS_TEMP hadoop.http.temp.dir kms-site.xml
KMS_HTTP_PORT hadoop.kms.http.port kms-site.xml
KMS_MAX_HTTP_HEADER_SIZE hadoop.http.max.request.header.sizeおよびhadoop.http.max.response.header.size kms-site.xml
KMS_MAX_THREADS hadoop.http.max.threads kms-site.xml
KMS_SSL_ENABLED hadoop.kms.ssl.enabled kms-site.xml
KMS_SSL_KEYSTORE_FILE ssl.server.keystore.location ssl-server.xml
KMS_SSL_KEYSTORE_PASS ssl.server.keystore.password ssl-server.xml

デフォルトのHTTPサービス

名前 説明
/conf 構成プロパティの表示
/jmx Java JMX管理インターフェイス
/logLevel クラスごとのログレベルの取得または設定
/logs ログファイルの表示
/stacks JVMスタックの表示
/static/index.html 静的なホームページ

サーブレット/conf/jmx/logLevel/logs、および/stacksへのアクセスを制御するには、kms-site.xmlで次のプロパティを構成します。

  <property>
    <name>hadoop.security.authorization</name>
    <value>true</value>
    <description>Is service-level authorization enabled?</description>
  </property>

  <property>
    <name>hadoop.security.instrumentation.requires.admin</name>
    <value>true</value>
    <description>
      Indicates if administrator ACLs are required to access
      instrumentation servlets (JMX, METRICS, CONF, STACKS).
    </description>
  </property>

  <property>
    <name>hadoop.kms.http.administrators</name>
    <value></value>
    <description>ACL for the admins, this configuration is used to control
      who can access the default KMS servlets. The value should be a comma
      separated list of users and groups. The user list comes first and is
      separated by a space followed by the group list,
      e.g. "user1,user2 group1,group2". Both users and groups are optional,
      so "user1", " group1", "", "user1 group1", "user1,user2 group1,group2"
      are all valid (note the leading space in " group1"). '*' grants access
      to all users and groups, e.g. '*', '* ' and ' *' are all valid.
    </description>
  </property>