~~ Licensed under the Apache License, Version 2.0 (the "License"); ~~ you may not use this file except in compliance with the License. ~~ You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, software ~~ distributed under the License is distributed on an "AS IS" BASIS, ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. --- Hadoop KMS - Documentation Sets ${project.version} --- --- ${maven.build.timestamp} Hadoop Key Management Server (KMS) - Documentation Sets ${project.version} Hadoop KMS is a cryptographic key management server based on Hadoop's <> API. It provides a client and a server components which communicate over HTTP using a REST API. The client is a KeyProvider implementation interacts with the KMS using the KMS HTTP REST API. KMS and its client have built-in security and they support HTTP SPNEGO Kerberos authentication and HTTPS secure transport. KMS is a Java web-application and it runs using a pre-configured Tomcat bundled with the Hadoop distribution. * KMS Client Configuration The KMS client <<>> uses the <> scheme, and the embedded URL must be the URL of the KMS. For example, for a KMS running on <<>>, the KeyProvider URI is <<>>. And, for a KMS running on <<>>, the KeyProvider URI is <<>> * KMS ** KMS Configuration Configure the KMS backing KeyProvider properties in the <<>> configuration file: +---+ hadoop.security.key.provider.path jceks://file@/${user.home}/kms.keystore hadoop.security.keystore.java-keystore-provider.password-file kms.keystore.password +---+ The password file is looked up in the Hadoop's configuration directory via the classpath. NOTE: You need to restart the KMS for the configuration changes to take effect. ** KMS Cache KMS caches keys for short period of time to avoid excessive hits to the underlying key provider. The Cache is enabled by default (can be dissabled by setting the <<>> boolean property to false) The cache is used with the following 3 methods only, <<>> and <<>> and <<>>. For the <<>> method, cached entries are kept for a maximum of 30000 millisecond regardless the number of times the key is being access (to avoid stale keys to be considered current). For the <<>> method, cached entries are kept with a default inactivity timeout of 600000 milliseconds (10 mins). This time out is configurable via the following property in the <<>> configuration file: +---+ hadoop.kms.cache.enable true hadoop.kms.cache.timeout.ms 600000 hadoop.kms.current.key.cache.timeout.ms 30000 +---+ ** Start/Stop the KMS To start/stop KMS use KMS's bin/kms.sh script. For example: +---+ hadoop-${project.version} $ sbin/kms.sh start +---+ NOTE: Invoking the script without any parameters list all possible parameters (start, stop, run, etc.). The <<>> script is a wrapper for Tomcat's <<>> script that sets the environment variables and Java System properties required to run KMS. ** Embedded Tomcat Configuration To configure the embedded Tomcat go to the <<>>. KMS pre-configures the HTTP and Admin ports in Tomcat's <<>> to 16000 and 16001. Tomcat logs are also preconfigured to go to Hadoop's <<>> directory. The following environment variables (which can be set in KMS's <<>> script) can be used to alter those values: * KMS_HTTP_PORT * KMS_ADMIN_PORT * KMS_LOG NOTE: You need to restart the KMS for the configuration changes to take effect. ** KMS Security Configuration *** Enabling Kerberos HTTP SPNEGO Authentication Configure the Kerberos <<>> file with the information of your KDC server. Create a service principal and its keytab for the KMS, it must be an <<>> service principal. Configure KMS <<>> with the correct security values, for example: +---+ hadoop.kms.authentication.type kerberos hadoop.kms.authentication.kerberos.keytab ${user.home}/kms.keytab hadoop.kms.authentication.kerberos.principal HTTP/localhost hadoop.kms.authentication.kerberos.name.rules DEFAULT +---+ NOTE: You need to restart the KMS for the configuration changes to take effect. *** KMS over HTTPS (SSL) To configure KMS to work over HTTPS the following 2 properties must be set in the <<>> script (shown with default values): * KMS_SSL_KEYSTORE_FILE=${HOME}/.keystore * KMS_SSL_KEYSTORE_PASS=password In the KMS <<>> directory, replace the <<>> file with the provided <<>> file. You need to create an SSL certificate for the KMS. As the <<>> Unix user, using the Java <<>> command to create the SSL certificate: +---+ $ keytool -genkey -alias tomcat -keyalg RSA +---+ You will be asked a series of questions in an interactive prompt. It will create the keystore file, which will be named <<.keystore>> and located in the <<>> user home directory. The password you enter for "keystore password" must match the value of the <<>> environment variable set in the <<>> script in the configuration directory. The answer to "What is your first and last name?" (i.e. "CN") must be the hostname of the machine where the KMS will be running. NOTE: You need to restart the KMS for the configuration changes to take effect. *** KMS Access Control KMS ACLs configuration are defined in the KMS <<>> configuration file. This file is hot-reloaded when it changes. KMS supports a fine grained access control via a set ACL configuration properties: +---+ hadoop.kms.acl.CREATE * ACL for create-key operations. If the user does is not in the GET ACL, the key material is not returned as part of the response. hadoop.kms.acl.DELETE * ACL for delete-key operations. hadoop.kms.acl.ROLLOVER * ACL for rollover-key operations. If the user does is not in the GET ACL, the key material is not returned as part of the response. hadoop.kms.acl.GET * ACL for get-key-version and get-current-key operations. hadoop.kms.acl.GET_KEYS * ACL for get-keys operation. hadoop.kms.acl.GET_METADATA * ACL for get-key-metadata and get-keys-metadata operations. hadoop.kms.acl.SET_KEY_MATERIAL * Complimentary ACL for CREATE and ROLLOVER operation to allow the client to provide the key material when creating or rolling a key. hadoop.kms.acl.GENERATE_EEK * ACL for generateEncryptedKey CryptoExtension operations hadoop.kms.acl.DECRYPT_EEK * ACL for decrypt EncryptedKey CryptoExtension operations +---+ ** KMS HTTP REST API *** Create a Key +---+ POST http://HOST:PORT/kms/v1/keys Content-Type: application/json { "name" : "", "cipher" : "", "length" : , //int "material" : "", //base64 "description" : "" } +---+ +---+ 201 CREATED LOCATION: http://HOST:PORT/kms/v1/key/ Content-Type: application/json { "name" : "versionName", "material" : "", //base64, not present without GET ACL } +---+ *** Rollover Key +---+ POST http://HOST:PORT/kms/v1/key/ Content-Type: application/json { "material" : "", } +---+ +---+ 200 OK Content-Type: application/json { "name" : "versionName", "material" : "", //base64, not present without GET ACL } +---+ *** Delete Key +---+ DELETE http://HOST:PORT/kms/v1/key/ +---+ +---+ 200 OK +---+ *** Get Key Metadata +---+ GET http://HOST:PORT/kms/v1/key//_metadata +---+ +---+ 200 OK Content-Type: application/json { "name" : "", "cipher" : "", "length" : , //int "description" : "", "created" : , //long "versions" : //int } +---+ *** Get Current Key +---+ GET http://HOST:PORT/kms/v1/key//_currentversion +---+ +---+ 200 OK Content-Type: application/json { "name" : "versionName", "material" : "", //base64 } +---+ *** Generate Encrypted Key for Current KeyVersion +---+ GET http://HOST:PORT/kms/v1/key//_eek?eek_op=generate&num_keys= +---+ +---+ 200 OK Content-Type: application/json [ { "versionName" : "encryptionVersionName", "iv" : "", //base64 "encryptedKeyVersion" : { "versionName" : "EEK", "material" : "", //base64 } }, { "versionName" : "encryptionVersionName", "iv" : "", //base64 "encryptedKeyVersion" : { "versionName" : "EEK", "material" : "", //base64 } }, ... ] +---+ *** Decrypt Encrypted Key +---+ POST http://HOST:PORT/kms/v1/keyversion//_eek?ee_op=decrypt Content-Type: application/json { "name" : "", "iv" : "", //base64 "material" : "", //base64 } +---+ +---+ 200 OK Content-Type: application/json { "name" : "EK", "material" : "", //base64 } +---+ *** Get Key Version +---+ GET http://HOST:PORT/kms/v1/keyversion/ +---+ +---+ 200 OK Content-Type: application/json { "name" : "versionName", "material" : "", //base64 } +---+ *** Get Key Versions +---+ GET http://HOST:PORT/kms/v1/key//_versions +---+ +---+ 200 OK Content-Type: application/json [ { "name" : "versionName", "material" : "", //base64 }, { "name" : "versionName", "material" : "", //base64 }, ... ] +---+ *** Get Key Names +---+ GET http://HOST:PORT/kms/v1/keys/names +---+ +---+ 200 OK Content-Type: application/json [ "", "", ... ] +---+ *** Get Keys Metadata +---+ GET http://HOST:PORT/kms/v1/keys/metadata?key=&key=,... +---+ +---+ 200 OK Content-Type: application/json [ { "name" : "", "cipher" : "", "length" : , //int "description" : "", "created" : , //long "versions" : //int }, { "name" : "", "cipher" : "", "length" : , //int "description" : "", "created" : , //long "versions" : //int }, ... ] +---+