Carpe Diem

備忘録

HashiCorp VaultのDynamic Secrets

概要

HashiCorp VaultにはDynamic Secretsという期限の付いた認証情報を動的に生成してパブリッククラウドやDBへのアクセスをセキュアに保つ仕組みが用意されています。

課題・背景

秘密情報とその周辺の認証を一元化し、適切な暗号化・Auditなどをしっかりしたとしても以下の課題が残っています。

  • 鍵情報を用意してもローテーション運用が大変
    • 退職者が出るたびにローテーションしなきゃいけない
  • 鍵の共有化
    • 影響範囲が分からず削除できない
    • 漏洩しても誰が使ったのか分からない
  • 起動時だけ秘密情報が必要なのに永続的にどこかに残すのがセキュアでない
    • ログやクラッシュレポートに秘密情報が吐き出されてしまったり

ref: https://www.hashicorp.com/blog/why-we-need-dynamic-secrets

Dynamic Secretsはそれを解決するための手段です。

環境

  • Vault 1.2.1

設定

AWS Secrets Engineの有効化

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

これでaws/というパスでAWS Secrets Engineが利用可能になりました。
デフォルトもaws/ですが、変更したい場合は指定します。

AWS Secrets Engineに権限を付与

IAM Roleで付与する場合

AWSインスタンスであれば、

christina04.hatenablog.com

こちらのようにVault Serverのインスタンス自体にIAM Roleを設定すればIAMユーザやアクセスキーの発行をせずに済みます。

IAMユーザで付与する場合

そうでない場合はIAMの権限を持ったIAMユーザを作成し、アクセスキーを発行してください。
マネージドポリシーのIAMFullAccessがあれば十分です。

f:id:quoll00:20190812140817p:plain

$ vault write aws/config/root \
    access_key=xxxx \
    secret_key=yyyy \
    region=ap-northeast-1

ちなみに一度書き込んだデータは読み取れないので漏洩の心配はないです。

$ vault read aws/config/root
Error reading aws/config/root: Error making API request.

URL: GET http://127.0.0.1:8200/v1/aws/config/root
Code: 405. Errors:

* 1 error occurred:
        * unsupported operation

動的生成するIAMユーザのRoleを設定

動的生成するIAMユーザにどんなRoleを付与するかを設定します。

例えばEC2リソースの全権限を付与する場合は以下です。
vault上ではec2-roleという名前にしています。こちらは任意です。呼び出す時に使用します。

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

検証

TTLの設定

renewの検証もしたいのでTTLを設定します。TTLについては前回の

VaultのTokenとLease - Carpe Diem

を参考にしてください。

$ vault write sys/mounts/aws/tune default_lease_ttl=10m max_lease_ttl=30m

確認します。

$ vault read sys/mounts/aws/tune
Key                  Value
---                  -----
default_lease_ttl    10m
force_no_cache       false
max_lease_ttl        30m

Lease(IAMユーザを動的に生成する)

aws/creds/:nameというパスに先程のec2-roleを設定してreadすると、以下のように10分限定のIAMユーザが生成されます。

$ vault read aws/creds/ec2-role
Key                Value
---                -----
lease_id           aws/creds/ec2-role/NdYoKvVnCWTpgWAy1t0EduKj
lease_duration     10m
lease_renewable    true
access_key         AxxxxxxxxxxxxxxxxxxxF
secret_key         7yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyk
security_token     <nil>

Webコンソールでも確認できます。

f:id:quoll00:20190812142346p:plain

Renew

max-ttlまでであれば、Lease期限を更新することもできます。

$ vault lease renew aws/creds/ec2-role/NdYoKvVnCWTpgWAy1t0EduKj
Key                Value
---                -----
lease_id           aws/creds/ec2-role/NdYoKvVnCWTpgWAy1t0EduKj
lease_duration     10m
lease_renewable    true

アクセスキーが再作成されるわけではないです。

Revoke

10分待てば自動でRevokeされますが、手動でもRevokeしてみます。

$ vault lease revoke aws/creds/ec2-role/NdYoKvVnCWTpgWAy1t0EduKj
All revocation operations queued successfully!

Webコンソールからも削除されたことを確認できます。

まとめ

秘密情報とその周辺の認証を一元化することは非常に重要ですが、それだけではまだ先に挙げた課題を解決できません。このDynamic Secretsによって

  • 永続的な鍵の運用、鍵の共有を避ける
  • 基本的に秘密情報をアプリケーションに持たせない
  • 仮にtokenが漏れたとしても被害を最小限に留める

といったこともできるようになります。

ソース