AWS KMS を利用して HashiCorp Vault Server の Unseal 作業を自動化する

Auto-Unseal 機能で、サーバーが再起動した場合でも Unseal されるように設定してみました。
2023.05.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。

最近、 HashiCorp Vault を勉強しています。今回は AWS KMS を利用して、 HashiCorp Vault Server の Unseal 作業を自動化してみようと思います。

Unseal 作業とは

HashiCorp Vault Server は、サーバー初期化後や再起動後に Seal (封印)状態で提供されます。Seal 状態では、シークレットの取得や認証の管理など、ほとんどの機能にアクセスできません。

そのため、 Vault Server を利用するには、 Unseal 作業が必要になります。

Unseal 作業はデフォルトで、 vault operator unseal コマンドまたは API を利用して行います。

# Vault Server の初期化

sh-5.2$ vault operator init
Unseal Key 1: roRigRRbbcXHiVW55w1xQ/Q5HwjaykcdUHZ6ppMqIk/t
Unseal Key 2: tADq6ssl+6ECZT3EwhbnTa7NcbuBDBu2pEYZuP2HqxNp
Unseal Key 3: +08Y8qS3Ppf+JLXDt0PXvtGIN3hfHjRNlSvhgaGpuUE/
Unseal Key 4: MCqr6URNg/LCICrJiOsd4xC4zHOochQ0mcA5/uDjgpnM
Unseal Key 5: uvCEU3YQ/CLYibVkgpCtxxCf1iWhL9pnbbgfVXgo948u

Initial Root Token: hvs.FjIXkI1ETPjTZMKhrdy64VhI

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated root key. Without at least 3 keys to
reconstruct the root key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

# Vault Server の初期化後のステータス確認

sh-5.2$ vault status
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    0/3
Unseal Nonce       n/a
Version            1.13.2
Build Date         2023-04-25T13:02:50Z
Storage Type       file
HA Enabled         false

# Unseal 作業 その 1
vault operator unseal roRigRRbbcXHiVW55w1xQ/Q5HwjaykcdUHZ6ppMqIk/t

# Unseal 作業 その 2
vault operator unseal tADq6ssl+6ECZT3EwhbnTa7NcbuBDBu2pEYZuP2HqxNp

# Unseal 作業 その 3
vault operator unseal +08Y8qS3Ppf+JLXDt0PXvtGIN3hfHjRNlSvhgaGpuUE/

# Unseal 作業後のステータス確認

sh-5.2$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    5
Threshold       3
Version         1.13.2
Build Date      2023-04-25T13:02:50Z
Storage Type    file
Cluster Name    vault-cluster-10632a7f
Cluster ID      fba28066-1105-490f-126d-5b672267adbc
HA Enabled      false

再起動時にも必要

再掲になりますが、 Unseal 作業は、 vault.service が再起動したタイミングでも都度必要になります。

以下実行結果の 26 行目の通り、vault.service を再起動すると、Sealed が true になっていることが確認できます。

# Vault Server の状態確認
sh-5.2$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    5
Threshold       3
Version         1.13.2
Build Date      2023-04-25T13:02:50Z
Storage Type    file
Cluster Name    vault-cluster-10632a7f
Cluster ID      fba28066-1105-490f-126d-5b672267adbc
HA Enabled      false

# vault.service の再起動
sh-5.2$ sudo systemctl restart vault.service

# Vault Server の状態確認
sh-5.2$ vault status
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    0/3
Unseal Nonce       n/a
Version            1.13.2
Build Date         2023-04-25T13:02:50Z
Storage Type       file
HA Enabled         false

再起動毎に vault operator unseal コマンドを利用して、手動で Unseal 作業を行うのはツラいです。

そのつらみを解消するのが、今回利用する Auto-Unseal 機能です。

Auto-Unseal 機能とは

Auto-Unseal 機能とは、クラウドプロバイダーで提供されている暗号化サービスを利用して、 Vault Server の Unseal 作業を自動化する機能です。

AWS では AWS KMS で Auto-Unseal 機能が利用できます。

Auto-unseal using AWS KMSより画像引用

やってみた

今回は AWS KMS を利用して、 Auto-Unseal 機能を利用してみようと思います。 OS は Amazon Linux 2023 を利用します。

HashiCorp Vault のインストール

まず初めに、HashiCorp Vault をインストールします。

以下のコマンドで、インストールを行います。

# HashiCorp レポジトリの追加
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo

# HashiCorp Vault のインストール
sudo dnf install -y vault

# HashiCorp Vault のバージョン確認
vault version

KMS Key の作成

次に AWS KMS のカスタマーマスターキーを作成します。

KMS コンソール画面から 「カスタマー管理型のキー」 を選択し、「キーの作成」でキーを作成します。

キーポリシーを以下のようにセットアップします。

アカウント ID および、 IAM ロールの部分は適宜置き換えてください。

{
  "Id": "key-consolepolicy",
  "Version": "2012-10-17",
  "Statement": [
      {
          "Sid": "Enable IAM User Permissions",
          "Effect": "Allow",
          "Principal": {
              "AWS": "arn:aws:iam::${アカウント ID}:root"
          },
          "Action": "kms:*",
          "Resource": "*"
      },
      {
          "Sid": "Allow Use Of The Key",
          "Effect": "Allow",
          "Principal": {
              "AWS": "arn:aws:iam::${アカウント ID}:role/${EC2 インスタンス紐づいた IAM ロール}"
          },
          "Action": [
            "kms:Encrypt",
            "kms:Decrypt",
            "kms:DescribeKey"
          ],
          "Resource": "*"
      }
  ]
}

設定ファイルの配置

AWS KMS 側のセットアップが終わったので、 Vault Server のセットアップを行います。

sudo vi /etc/vault.d/vault.hcl コマンドで以下のように書き換え、 Vault Server を設定します。

/etc/vault.d/vault.hcl

ui = true
log_level = "INFO"

storage "file" {
  path = "/opt/vault/data"
}

listener "tcp" {
  address = "0.0.0.0:8200"
  tls_disable = 1
}

# Auto-Unseal 機能
seal "awskms" {
  region = "ap-northeast-1"
  kms_key_id = "作成した AWS KMS のキー ID または ARN"
}

書き換えが完了したら、 vault.serviceを起動します。

# vault.service サービスの起動
sudo systemctl start vault.service

## vault.service のステータス確認
sudo systemctl status vault

実行結果を確認すると、 Vault Server の 初期化が完了していないため、いくつかエラーが出ていることがわかります。

sudo systemctl start vault.service

## vault.service のステータス確認
sudo systemctl status vault

● vault.service - "HashiCorp Vault - A tool for managing secrets"
     Loaded: loaded (/usr/lib/systemd/system/vault.service; enabled; preset: disabled)
     Active: active (running) since Wed 2023-05-03 08:52:19 UTC; 1min 3s ago
       Docs: https://www.vaultproject.io/docs/
   Main PID: 3346 (vault)
      Tasks: 7 (limit: 4562)
     Memory: 70.1M
        CPU: 187ms
     CGroup: /system.slice/vault.service
             └─3346 /usr/bin/vault server -config=/etc/vault.d/vault.hcl

May 03 08:52:59 ip-172-31-12-206.ap-northeast-1.compute.internal vault[3346]: 2023-05-03T08:52:59.787Z [INFO]  core: stored unseal keys supported, attempting fetch
May 03 08:52:59 ip-172-31-12-206.ap-northeast-1.compute.internal vault[3346]: 2023-05-03T08:52:59.788Z [WARN]  failed to unseal core: error="stored unseal keys are supported, but none were found"
May 03 08:53:04 ip-172-31-12-206.ap-northeast-1.compute.internal vault[3346]: 2023-05-03T08:53:04.789Z [INFO]  core: stored unseal keys supported, attempting fetch
May 03 08:53:04 ip-172-31-12-206.ap-northeast-1.compute.internal vault[3346]: 2023-05-03T08:53:04.789Z [WARN]  failed to unseal core: error="stored unseal keys are supported, but none were found"

続いて、 vault operator init で Vault Server を初期化します。

# Vault 接続先アドレスの変更
export VAULT_ADDR='http://127.0.0.1:8200'

# Vault Server を初期化
vault operator init

# Vault Server の状態確認
vault status

コマンドを実行すると Recovery Key と Initial Root Token が提供されます。

Auto-Unseal 機能を利用する場合、 Unseal Key の代わりに Recovery Key が提供されます。

Recovery Key は、 Root Token の再生成などで利用するため、無くさないよう注意です。

sh-5.2$ vault operator init

Recovery Key 1: g9ivJfz9fEAMiDB2syYpqX9QUds3UCtTzW6FXHJZf1+m
Recovery Key 2: M6dFEBQG6zDRWtp6JM7vli7v/vvRZMkD07rRi/+P1k6c
Recovery Key 3: xhpcTeUdVbe0ppm2TlXsRTnqwWQfcUeLOSTGRVwCVZle
Recovery Key 4: Le7UdabGcHXtazYjcJbuOTRI0ZWBaY/g/Qv3jPj8aRNI
Recovery Key 5: meI4or8lQ1NlS8TP0Eu0eNz46AaEKE5lmzSfTz0Tt17n

Initial Root Token: hvs.UoeCV061Ultto8UY0Z3fe5OR

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.

また、 vault status コマンドの結果から Unseal 作業が自動化され、Vault Server が利用可能になっていることが確認できます。

sh-5.2$ vault status
Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
Total Recovery Shares    5
Threshold                3
Version                  1.13.2
Build Date               2023-04-25T13:02:50Z
Storage Type             file
Cluster Name             vault-cluster-c9fa2361
Cluster ID               f4c9c8b5-9524-cb3a-49ec-34ca01200ebd
HA Enabled               false

Vault を再起動してみる

Auto-Unseal 機能により、vault.serviceを再起動した場合でも自動的に Unseal されるようになりました。ファイルの追加とキー作成のみとハードル低く、とても便利な機能だと思いました!

sh-5.2$ vault status
Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
Total Recovery Shares    5
Threshold                3
Version                  1.13.2
Build Date               2023-04-25T13:02:50Z
Storage Type             file
Cluster Name             vault-cluster-488b5ba3
Cluster ID               9e671177-22d8-c18d-49a7-886497f3236d
HA Enabled               false
sh-5.2$ sudo systemctl restart vault
sh-5.2$ vault status
Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
Total Recovery Shares    5
Threshold                3
Version                  1.13.2
Build Date               2023-04-25T13:02:50Z
Storage Type             file
Cluster Name             vault-cluster-488b5ba3
Cluster ID               9e671177-22d8-c18d-49a7-886497f3236d
HA Enabled               false

sh-5.2$ sudo systemctl status vault
● vault.service - "HashiCorp Vault - A tool for managing secrets"
     Loaded: loaded (/usr/lib/systemd/system/vault.service; disabled; preset: disabled)
     Active: active (running) since Wed 2023-05-03 09:18:42 UTC; 2min 28s ago
       Docs: https://www.vaultproject.io/docs/
   Main PID: 2535 (vault)
      Tasks: 8 (limit: 4562)     Memory: 74.2M
        CPU: 663ms
     CGroup: /system.slice/vault.service             └─2535 /usr/bin/vault server -config=/etc/vault.d/vault.hcl

May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.151Z [INFO]  core: successfully mounted: type=token version="v1.13.2+builtin.vault" path=token/ namespac>
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.151Z [INFO]  rollback: starting rollback manager
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.151Z [INFO]  core: restoring leases
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.152Z [INFO]  identity: entities restored
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.152Z [INFO]  identity: groups restored
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.152Z [INFO]  expiration: lease restore complete
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.152Z [INFO]  core: usage gauge collection is disabled
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.185Z [INFO]  core: post-unseal setup completeMay 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.185Z [INFO]  core: vault is unsealed
May 03 09:18:42 ip-172-31-10-101.ap-northeast-1.compute.internal vault[2535]: 2023-05-03T09:18:42.185Z [INFO]  core: unsealed with stored key

まとめ

以上、「AWS KMS を利用して HashiCorp Vault Server の Unseal 作業を自動化する」でした。

自動復旧の面で見ても、 Auto-Unseal 機能は重要な役割だと思いました。これからも便利な機能をご紹介できればと思います。

ハンズオンも提供されているため、ぜひお試しいただけますと幸いです。

以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!