てくなべ (tekunabe)

ansible / network automation / 学習メモ

HashiCorp Vault の動的シークレット機能で AWS の一時的 な IAM ユーザーを作成してみた

はじめに

Software Design 2022年5月号の Vault の連載の記事は「動的シークレットで安全性を高めよう」という内容でした。

興味が湧いたので、HashiCorp Learn の Dynamic Secrets も合わせて読んだうえで、試してみました。

AWS の IAM ユーザーの一時的に作成するという内容です。このユーザーの有効期限を短く(デフォルト 768h?、長すぎて検証できず)するためには、少し設定が必要のようでした。その設定をあわせて、私が試してみた内容をまとめます。

AWS シークレットエンジンの有効化

デフォルトでは無効化されているようで、まずは有効化します。

$ vault secrets enable -path=aws aws
Success! Enabled the aws secrets engine at: aws/   # 成功

確認のために vault secrets list を実行した結果は以下のとおりです。

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
aws/          aws          aws_d7104241          n/a
cubbyhole/    cubbyhole    cubbyhole_985a6a5f    per-token private secret storage
identity/     identity     identity_69fd0f2a     identity store
secret/       kv           kv_7e37a4af           key/value secret storage
sys/          system       system_d0a77cbd       system endpoints used for control, policy and debugging

 AWS のアクセスキーとシークレットキーを設定

まず環境変数に AWS のアクセスキーとシークレットキーを設定します。

$ export AWS_ACCESS_KEY_ID=AKIAxxxxxxxxxxxxxxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

設定した環境変数を Vault 側から参照して設定します。

$ vault write aws/config/root \
    access_key=$AWS_ACCESS_KEY_ID \
    secret_key=$AWS_SECRET_ACCESS_KEY \
    region=ap-northeaset-1
Success! Data written to: aws/config/root   # 成功

確認のために vault read aws/config/root を実行した結果は以下のとおりです。

$ vault read  aws/config/root
Key                  Value
---                  -----
access_key           AKIAxxxxxxxxxxxxxxxx
iam_endpoint         n/a
max_retries          -1
region               ap-northeaset-1
sts_endpoint         n/a
username_template    {{ if (eq .Type "STS") }}{{ printf "vault-%s-%s"  (unix_time) (random 20) | truncate 32 }}{{ else }}{{ printf "vault-%s-%s-%s" (printf "%s-%s" (.DisplayName) (.PolicyName) | truncate 42) (unix_time) (random 20) | truncate 64 }}{{ end }}

ロールの作成

次は、一時的に作成される IAM ユーザー に割り当てるロールを作成します。

ここでは、HashiCorp Learn の Dynamic Secretsにあるものを利用させていただきます。

$ vault write aws/roles/my-role \
        credential_type=iam_user \
        policy_document=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1426528957000",
      "Effect": "Allow",
      "Action": [
        "ec2:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
EOF

TTL の変更

検証のため、IAM ユーザーの有効期限を短くします。

通常の TTL を3分、延長できる最長 TTL を 10分にします。(こちらの記事を参考にさせていだきました。)

$ vault write sys/mounts/aws/tune default_lease_ttl=3m max_lease_ttl=10m
Success! Data written to: sys/mounts/aws/tune

(公式ドキュメント上でこの指定の方法を見つけられていません・・)

確認のため、vault read sys/mounts/aws/tune

$ vault read sys/mounts/aws/tune
Key                  Value
---                  -----
default_lease_ttl    3m        # 変更しない場合は 768h
description          n/a
force_no_cache       false
max_lease_ttl        10m       # 変更しない場合は 768h

動的シークレトの取得

いよいよ動的シークレットの取得です。ここでは、つまり 一時的な IAM ユーザーの作成です。

$ vault read aws/creds/my-role
Key                Value
---                -----
lease_id           aws/creds/my-role/ude94KFfvkP5uhv0ZeR1XXeP
lease_duration     3m       # 変更しない場合は 768h
lease_renewable    true
access_key         AKIAyyyyyyyyyyyyyyyy
secret_key         yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
security_token     <nil>

動作確認

別のターミナルで、先程表示されたアクセスキーとシークレットキーを使って、かんたんな動作確認をします。

EC2 に対するアクス権限があるはずなので aws ec2 describe-instances で一覧表示を試します。

$ aws ec2 describe-instances
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-hogehoge",
                    "InstanceId": "i-fugafuga",
# ...(略)...

無事に表示されました。

念のため、許可されていない他の操作ができないことも確認します。

$ aws s3 ls

An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

ロールを作成してから3分以内に AWS のネジメントコンソール上で一時的な IAM ユーザーがあることを確認します。

ユーザーが作成された

なるほど。

このまま3分ほど経過すると、vault server -dev でサーバーを起動しているターミナルで以下のログが表示されました。

2022-05-01T18:00:49.945+0900 [INFO]  expiration: revoked lease: lease_id=aws/creds/my-role/ude94KFfvkP5uhv0ZeR1XXeP

IAM ユーザーが削除されたようなので、再度 AWS のネジメントコンソールを確認すると、たしかにいなくなっていました。

削除された

ということは、先程できていた aws ec2 describe-instances はできなくなっているはずなので確認します。

$ aws ec2 describe-instances

An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials

無事、できなくなっていました。

まとめ

動的シークレットの機能を利用して、AWS の一時的 な IAM ユーザーを作成してみました。

vault lease revoke で明示的に削除もできますが、有効期限で自動削除されるのは安心です。

参考

TTL の設定変更はこちらの記事を参考にさせていただきました。

christina04.hatenablog.com