はじめに
Software Design 2022年5月号の Vault の連載の記事は「動的シークレットで安全性を高めよう」という内容でした。
興味が湧いたので、HashiCorp Learn の Dynamic Secrets も合わせて読んだうえで、試してみました。
AWS の IAM ユーザーの一時的に作成するという内容です。このユーザーの有効期限を短く(デフォルト 768h?、長すぎて検証できず)するためには、少し設定が必要のようでした。その設定をあわせて、私が試してみた内容をまとめます。
- 環境
- Red Hat Enterprise Linux 8.4
- Vault v1.10.0
vault server -dev
での起動済(かんたんな検証目的のため) 参考
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 の設定変更はこちらの記事を参考にさせていただきました。
他
👏ちなみに実運用で CI/CD と組み合わせて使う場合などは、IAM ユーザーではなく STS トークンを発行する方法もオススメです。IAM ユーザーは作成してから全リージョンで使えるようになるまで多少の遅延があり、直後利用だとコケたりしますが、STS ならその心配がありません。https://t.co/g9ZMIRnVdn https://t.co/i11JzQ7ewN
— Shohei Maeda (@jrsyo) 2022年5月4日