目次
※こちらの記事はCloud Native Week2023春のイベントに登壇した内容を元に作成しています!
お久しぶりでございます!よっしーです。
シークレット管理、そしてデータ暗号化用のセキュリティツールとして広く使われています、
HashiCorp Vault ですが、実際はどのようにアクセス対象となる各種サービスに対して
Vault から操作・設定されるのかを、AWS CLI でのアクセス許可のための IAM 設定を
通して見ていきたいと思います!
HashiCorp Vault のインストール・初期設定
今回は Vault 自体の設定を簡易化するため、「開発モード」を使用します。
- 開発モードでは、いくつかの Vault のセキュリティ機能が解除された状態で起動されるため、 Vault の動作検証には便利な機能ですが、決して本番環境では使用しないようにしましよう。
1、インストール
以下のコマンドを実行。今回 Vault 起動サーバ の OS は CentOS7 を使用。
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.bashicorp.com/RHEL/bashicorp.repo
$ sudo yum -y install vault
これでインストールは完了です。簡単ですね。
正しくインストールできたかの確認は “vault” コマンドを実行。ヘルプが表示されれば OK!
2、「開発モード」で起動
Vault を開発モードで起動するためには以下のコマンドを実行。
$ sudo vault server -dev (-dev-listen-address "0.0.0.0:8200") &
-----
-dev : 開発モードで起動 (tlsを使用するには -dev-tls を使用。証明書も自動発行される)
-dev-listen-address : 指定した IP からの接続が許可される。このオプションを省略すると
127.0.0.1:8200 が指定され、localhost からのみ接続が許可される。
上記のコマンドを実行すると下記のような情報が表示される。
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.
You may need to set the following environment variables:
$ export VAULT_ADDR='http://127.0.0.1:8200'
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: jUAuIs7sXVK4/ftpWBV8G8RebH3V4nAoWkr2EB5rOMY=
Root Token: hvs.An6gQBYX587rxSXnYyKR07TY
Development mode should NOT be used in production installations!
ここで重要なのは、”Root Token”。 メモに控えておきましょう。
開発モードでは全ての登録データがメモリー上に保存されるため、
vault プロセスの再起動を実行すると登録した全てのデータが消去されます!
3、vault にアクセスするための環境設定。
Vault 起動サーバにて以下の環境変数を設定
$ export VAULT_ADDR='http://127.0.0.1:8200'
$ export VAULT_TOKEN='hvs.An6gQBYX587rxSXnYyKR07TY'
----
localhost 以外からのアクセスを許可した場合、'VAULT_ADDR' にはVault起動サーバのIPを指定。
例) export VAULT_ADDR='http://123.45.67.890:8200'
以下のコマンドを実行し、status が表示されたらアクセス成功!
$ vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.13.2
Build Date 2023-04-25T13:02:50Z
Storage Type inmem
Cluster Name vault-cluster-08b1b449
Cluster ID 687fac1b-4b87-d7d3-e1e4-3bc0614c403e
HA Enabled false
Vault 用 AWS ユーザの作成
Vault で期限付き AWS credential 発行のために、Vault で作成した IAM 情報を登録するための AWS ユーザを作成します。
1、AWS マネジメントコンソールの 「IAM → ユーザ → ユーザ追加」から新規ユーザを作成。
- 「ポリシー」および「セキュリティ認証情報」を設定するためマネジメントコンソールアクセスを許可。
2、AWS マネジメントコンソールから作成したユーザにログインし、
「セキュリティ認証情報」を開く。
- アクセスキーを作成。
- コマンドラインインターフェイス (CLI) 用を選択
- 作成された ACCESS_KEY_ID と SECRET_ACCESS_KEY をメモに控える。
- 必要であれば、「MFA」の設定も可能
3、ポリシーを設定。Vault による IAM の操作が必要となるための、以下のポリシーを追加。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"iam:DeleteAccessKey",
"iam:AttachUserPolicy",
"iam:DeleteUserPolicy",
"iam:DeleteUser",
"iam:ListUserPolicies",
"iam:CreateUser",
"iam:CreateAccessKey",
"iam:RemoveUserFromGroup",
"iam:AddUserToGroup",
"iam:ListGroupsForUser",
"iam:PutUserPolicy",
"iam:ListAttachedUserPolicies",
"iam:GetUser",
"iam:DetachUserPolicy",
"iam:ListAccessKeys"
],
"Resource": [
"arn:aws:iam::121467996308:user/*",
"arn:aws:iam::121467996308:group/*"
]
}
]
}
Vault で期限付き AWS IAM Credential を作成
それでは、vault 起動サーバにて、期限付き AWS IAM Credential を作成してみましょう!
1、vault で「AWS シークレットエンジン」を起動
まずは vault で AWS credential を操作できるよう、以下のコマンドで
シークレットエンジンを起動。
$ vault secrets enable -path=aws aws
------
Success! Enabled the aws secrets engine at: aws/
と表示されれば成功
2、Vault 用 AWS ユーザのアクセスキー情報を Vault に登録
$ vault write aws/config/root \
access_key=<Vault用ユーザのACCESS_KEY_ID> \
secret_key=<Vault用ユーザのSECRET_ACCESS_KEY> \
region=ap-northeast-1
Vault 用 AWS ユーザのアクセスキー情報は Vault サーバに保存されるため、
サーバまたは、クラインアント側のファイル等に保存する必要はなし。
3、期限付き AWS IAM Credential に付与するロールの登録
Vault で作成する期限付き AWS IAM Credential には個別に ロールを付与することが可能。
今回は、
- EC2 に対する全操作権限を持つロール
- s3 に対する全操作権限を持つロール
の2つのロールを登録。
EC2 に対する全操作権限を持つロール
$ vault write aws/roles/my-role-ec2 \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
EOF
------
Success! Data written to: aws/roles/my-role-ec2
と表示されれば成功
s3 に対する全操作権限を持つロール
$ vault write aws/roles/my-role-s3 \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
EOF
------
Success! Data written to: aws/roles/my-role-s3
と表示されれば成功
4、期限付き AWS IAM Credential に対する期限の設定
期限付き AWS IAM Credential の期限のデフォルト値および、最大値は共に
768時間 (32日間)
に設定。
今回は検証のため以下のコマンドで、デフォルト値を 3 分、最大値を10 分に設定
$ vault write sys/mounts/aws/tune default_lease_ttl=3m max_lease_ttl=10m
------
Success! Data written to: sys/mounts/aws/tune
と表示されれば成功
5、期限付き AWS IAM Credential の作成
以下のコマンドを実行
ロール「my-role-ec2」が付与された credential の作成
$ vault read aws/creds/my-role-ec2
------
Key Value
--- -----
lease_id aws/creds/my-role-ec2/gGKtCpjqY46azXfVFICN1OKk
lease_duration 3m
lease_renewable true
access_key AKIARYSAORCKHHJFJX57
secret_key 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
security_token <nil>
------
と表示されれば成功
ここに表示された access_key および secret_key が期限付き AWS IAM Credential となる
同様に、
ロール「my-role-s3」が付与された credential の作成
$ vault read aws/creds/my-role-s3
------
Key Value
--- -----
lease_id aws/creds/my-role-s3/y3o8Z4qZ1tOrDhrwGJoKZbLS
lease_duration 3m
lease_renewable true
access_key AKIARYSAORCKAOKN26GM
secret_key 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
security_token <nil>
------
と表示されれば成功
期限付き AWS IAM Credential を使ってみる
作成された期限付き AWS IAM Credential を使うには、出力された access_key と secret_key を
AWS CLI を実行するクライアントに登録し、aws コマンドを実行する。
・ロール「my-role-ec2」が付与された credential の使用
1、環境変数に access_key と secret_key を登録
以下のコマンドを実行
$ export AWS_ACCESS_KEY_ID=AKIARYSAORCKHHJFJX57
$ export AWS_SECRET_ACCESS_KEY=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
2、aws コマンドを実行する
$ aws ec2 describe-instances --output=table --query 'Reservations[].Instances[].{InstanceId: InstanceId}'
-------------------------
| DescribeInstances |
+-----------------------+
| InstanceId |
+-----------------------+
| i-0c0a56ddfxxxxxxxx |
| i-0ca5a69b2xxxxxxxx |
| i-0fa881c65xxxxxxxx |
| i-037a5f514xxxxxxxx |
| i-020134377xxxxxxxx | | i-06447b09cxxxxxxxx |
| i-0aa819774xxxxxxxx |
+-----------------------+
ーーーー
EC2 のリストが表示された
$ aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
ーーーー
s3 にはアクセスできない
〜〜〜
credential 作成後 3 分経過
〜〜〜
$ aws ec2 describe-instances --output=table --query 'Reservations[].Instances[].{InstanceId: InstanceId}'
An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
ーーーー
EC2 にアクセスできない
・ロール「my-role-s3」が付与された credential の使用
1、環境変数に access_key と secret_key を登録
以下のコマンドを実行
$ export AWS_ACCESS_KEY_ID=AKIARYSAORCKAOKN26GM
$ export AWS_SECRET_ACCESS_KEY=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
2、aws コマンドを実行する
$ aws s3 ls
2021-01-27 13:38:39 aaaaaa
2020-08-28 14:07:37 bbbbbb
2020-06-19 03:07:21 cccccc
2020-06-19 03:08:38 dddddd
2021-03-02 12:33:00 eeeeee
2020-06-19 03:28:47 ffffff
2020-10-08 18:06:08 gggggg
ーーーー
s3 のバケットリストが表示された
$ aws ec2 describe-instances --output=table --query 'Reservations[].Instances[].{InstanceId: InstanceId}'
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
ーーーー
EC2 にはアクセスできない
〜〜〜
credential 作成後 3 分経過
〜〜〜
$ aws s3 ls
An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.
ーーーー
s3 にアクセスできない
AWS では何が起こっている?
Vault による 期限付き AWS IAM Credential が作成されると、
Vault により IAM ユーザが作成される。
・ロール「my-role-ec2」が付与された credential 作成時
下図のように、「vault-root-my-role-ec2」から始まる IAM ユーザが作成される
このユーザには、
- ポリシー 「my-role-ec2」がインラインポリシーとして設定
- “vault read” 実行時に表示されたアクセスキー情報が登録
されている。また、ポリシー「my-role-ec2」には
EC2 に対する全操作権限を持つロールが付与されている。
・ロール「my-role-s3」が付与された credential 作成時
下図のように、「vault-root-my-role-s3」から始まる IAM ユーザが作成される
このユーザには、
- / ポリシー 「my-role-s3」がインラインポリシーとして設定
- “vault read” 実行時に表示されたアクセスキー情報が登録
されている。また、ポリシー「my-role-s3」には
s3 に対する全操作権限を持つロールが付与されている。
また、これらの IAM ユーザは
“lease_duration” で設定されている期間が過ぎると、
Vault により自動的に削除されるため、
期限が過ぎた AWS IAM Credential は使用できなくなる。
更に、これらの IAM ユーザは以下のコマンドにより手動で削除も可能
$ vault lease revoke <lease_id>
例) $ vault lease revoke aws/creds/my-role-s3/y3o8Z4qZ1tOrDhrwGJoKZbLS
まとめ
シークレット管理のために多くの機能をもつ HashiCorp Vault ですが、シークレット管理の手順は意外と分かりやすく、シンプルな構造でした。
今回ご紹介した 期限付き AWS IAM Credential は一時的に AWS で作業したいゲストユーザにアクセス権を提供できる有効な手段となると思われます。
また、Vault では Google Cloud (GCP) や Microsoft Azure にも同様な機能が提供できるため、幅広く活用できるでしょう。