Cloud KMSをVaultで使ってみる

目次

  1. 初めに
  2. 動作環境
  3. 環境の事前準備
  4. Cloud KMSとService Accountの作成
  5. Vaultに設定を入れていく
  6. 終わりに

1. 初めに

Vaultではマスターキーを生成するためにShared Keyを利用していますが、Shared KeyはVaultを初期化したときに出力され、その情報を保存しておかないといけません。またVault Serverを起動しなおすたびにそのShared Keyを入力しないといけないので手間になってしまいます。

そのためShared Keyの代わりにCloud KMSを利用することでその手間を省く仕組みがありますので、今回はそれを試したいと思います。

2. 動作環境

3. 環境の事前準備

まずはStorage Backendの設定からしていきます。以前Storage BackendをGCPに設定したことがあるのでそのまま使ってみたいと思います。Storageの設定は下記記事に記載していますが、実施したコマンドだけここに乗せておきます。

kobatako.hatenablog.com

$ gsutil mb gs://kobaru-vault-sample-bucket
Creating gs://kobaru-vault-sample-bucket/...
$ gcloud iam service-accounts create vaultstorage
$ gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/storage.objectAdmin"
$ gcloud iam service-accounts keys create vaultstorage-key.json --iam-account=vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Storage Backendの設定が完了したので次はCloud KMSの設定をしていこうと思います。

4. Cloud KMSとService Accountの作成

Cloud KMSでは最初にキーリングと鍵を作成していきます。

$ gcloud kms keyrings create vault-ring --location asia-northeast1
$ gcloud kms keys create vault-key --location asia-northeast1 --keyring vault-ring --purpose encryption

--purpose はどのような鍵を生成するかを指定するオプションで、Vaultでは対象暗号化の鍵を利用するので encryption を指定し対象暗号化の鍵を作成します。

次にService Accountを作成していきます。

$ gcloud iam service-accounts create vaultkey
Created service account [vaultkey].

Cloud KMSへのアクセスするためのRoleを作成します。ドキュメントにCloud KMSを利用するための最低限の権限が乗っているのでそれを参考に作成します。

$ gcloud iam roles create vaultKey --permissions="cloudkms.cryptoKeyVersions.useToEncrypt,cloudkms.cryptoKeyVersions.use
ToDecrypt,cloudkms.cryptoKeys.get" --project=${GOOGLE_CLOUD_PROJECT}
Created role [vaultKey].
etag: BwWaumyuAiI=
includedPermissions:
- cloudkms.cryptoKeyVersions.useToDecrypt
- cloudkms.cryptoKeyVersions.useToEncrypt
- cloudkms.cryptoKeys.get
name: projects/sample-project/roles/vaultKey
stage: ALPHA
title: vaultKey

ちなみに下記がRoleに割り当てた権限になります。

  • cloudkms.cryptoKeyVersions.useToEncrypt : 対象暗号鍵を使って暗号化する
  • cloudkms.cryptoKeyVersions.useToDecrypt: 対象暗号鍵を使って復号する
  • cloudkms.cryptoKeys.get: 暗号鍵を取得する

作成したRoleをService Accountに割り当てたいと思います。

$ gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:vaultkey@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="projects/${GOOGLE_CLOUD_PROJECT}/roles/vaultKey"

Roleまで割り当てることができたので次にvaultkey Service Accountのクレデンシャルを取得します。

$ gcloud iam service-accounts keys create vaultkey-key.json --iam-account=vaultkey@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

作成が完了しました。これで一通りGCP上での作業は終了になります。 次にVaultの設定をしていきます。

5. Vaultに設定を入れていく

まずはVaultのconfig設定に seal を追加します。

seal "gcpckms" {
  credentials = "/home/hogehoge/credentials/vaultkey-key.json"
  project     = "sample-project"
  region      = "asia-northeast1"
  key_ring    = "vault-ring"
  crypto_key  = "vault-key"
}

credentials にはService Accountの鍵のJSONファイルのパスを指定してあげます。

project にはキーリングを作成したプロジェクトを指定します。

region にもキーリングを作成したリージョンを指定します。

key_ringcrypto_key には先ほど作成したキーリングと鍵の名前を入れます。

設定は異常になりますので起動させてみます。

$ vault server -config=config/config.hcl
==> Vault server configuration:

      GCP KMS Crypto Key: vault-key
        GCP KMS Key Ring: vault-ring
         GCP KMS Project: sample-project
          GCP KMS Region: asia-northeast1
               Seal Type: gcpckms
                     Cgo: disabled
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: gcs (HA disabled)
                 Version: Vault v1.3.0
             Version Sha: 4083c36aa0630faafb7c04be62c4940299880bc9+CHANGES

==> Vault server started! Log data will stream in below:

2019-12-28T03:17:51.591Z [INFO]  proxy environment: http_proxy= https_proxy= no_proxy=
2019-12-28T03:17:52.513Z [WARN]  no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set
2019-12-28T03:17:52.817Z [INFO]  core: stored unseal keys supported, attempting fetch
2019-12-28T03:17:53.129Z [WARN]  failed to unseal core: error="stored unseal keys are supported, but none were found"

起動できましたね。ちなみに failed to unseal core: error="stored unseal keys are supported, but none were found" っと出てますが失敗してるわけではありません。WARNですし。

後で vault operator init をすれば問題なく消えるのでご安心を。自分はこれが出まくって焦ってました。。。

では別ターミナルを立ち上げてVaultの初期化処理をします。

$ export VAULT_ADDR='http://127.0.0.1:8200'
$ vault operator init
Recovery Key 1: r7CoxTUKzGkSbRGIl7aKiFdfk72o4CKlYejLK9b2qr6W
Recovery Key 2: WtzJLIkHvSgsMlZ3u3aOBvuhtd9SEXJYVd5m4VcqVaTN
Recovery Key 3: AppF9fDFocx9/oCq0U9f/CEmxCcwDXWc+WDsO22qO5si
Recovery Key 4: 2sTgtPhtq1940WHQDKGnVQz//5xEQcd1UnBjeHF/jMC/
Recovery Key 5: eoWxLfMYQhF7IKmf4/4VaEFCN7exRUDzm65rL+Q5N69k

Initial Root Token: s.F8NdXgXa4AJLLYcq9Mc19ez6

Success! Vault is initialized

Recovery key initialized with 5 key shares and a key threshold of 3. Please
securely distribute the key shares printed above.

Root Tokenを使ってログインをします。

$ vault login s.F8NdXgXa4AJLLYcq9Mc19ez6
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                s.F8NdXgXa4AJLLYcq9Mc19ez6
token_accessor       cHwLgO59RteazOjNhxG0TZLn
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

無事にログインできましたね。Cloud KMSを使わずに起動させた場合は Unseal Keyを入力する必要があったのですが、Cloud KMSを利用することでその手間が省けるようになりました。

6. 終わりに

今回はCloud KMSの設定をしていきました。設定としては非常に簡単ですしk8s上でVaultを動かすときなどはCloud KMSを使うことで非常に使い勝手がよくなるので今回やってみようと思いました。 いつかk8s上でVaultを動かしたいので機会があればやってみたいと思います。