リモート開発メインのソフトウェア開発企業のエンジニアブログです

aws-vault を使って AWS IAM のクレデンシャルを安全に管理する

最近、ローカルの開発 PC 上での AWS IAM のクレデンシャルの管理に aws-vault を使い始めてみた所、結構良さそうだったので紹介します。

ローカルでの IAM のクレデンシャル管理について

AWS 上のコンピューティングリソース (EC2, ECS 等) では IAM Role を使うので特に気を使う事はないと思いますが、開発者個人の PC で管理する上では注意が必要です。
AdministratorAccess 等強めの権限が付いた IAM User のクレデンシャルを誤ってインターネット上に公開してしまい、悪用された等のトラブルはよく聞くと思います。

そこはツールを使う等してある程度防ぐ事は可能としても、 AWS での開発フローにはそもそも根本的な問題があります。それは、クレデンシャルの保存を平文で行っていると言う点です。

AWS の CLI や AWS SDK の仕様上、クレデンシャルは “Profile” と言う形で ini ファイル形式で ~/.aws/credentials に保存する事ができ、この仕組みを使うと作業する AWS アカウントや権限を簡単に切り替えられるので便利なのですが、PC が万が一攻撃された場合や紛失等をして第 3 者に渡ると、一挙にクレデンシャルが漏れると言うリスクがあります。

※過去に ESLint や PHP 本体に悪意のあるコードが埋め込まれると言う事件がありましたが、この手の攻撃は普通のアンチウィルスでは防ぐのは難しそうです。

そこで、クレデンシャルそのものは暗号化された安全な状態で保存しつつ、なるべくこれまでの使い勝手を損なわないツールがあれば良さそうですが、まさしく aws-vault が要件を満たしていました。

aws-vault について

公式リポジトリ はこちらになります。また、 aws-vault の紹介記事がこちら (何故か見れなくなっているので Web Acrhive になります) にあり、99designs と言うスタートアップが 2007 年から AWS を運用するにあたって直面してきたクレデンシャル管理について対処すべく作ったと言う経緯が書かれています。

Go で書かれたシンプルな作りになっており、機能の根幹となっている暗号化については、デフォルトでは OS 標準の物をバックエンドとする作りになっています。macOS なら Keychain, Windows なら Credential Manager です。また Unix や Linux で使う場合は GNOME Keyring や KWallet が使え、そもそも全 OS 共通で単に通常のファイルシステム (内部には JWT が使われる) を使う事も可能なようです。

また、登場から 5 年以上も経過しており実績も多数あるので、積極的に利用しても良いと言えるのではないでしょうか。

尚、本記事では macOS + Keychain での利用例を紹介します。

インストール

色々方法はありますが macOS で使う場合は Homebrew を使うのが簡単です:

$brew install --cask aws-vault
...

$ aws-vault --version
v6.3.1

クレデンシャルの登録

aws-vault add 登録したいプロファイル名 と言う形式で add サブコマンドを実行します。因みにプロファイルですが、これまで CLI 等で使ってきたプロファイルと同等の物と考えて OK です:

$ aws-vault add test-profile
Enter Access Key ID: (アクセスキー ID を入力)
Enter Secret Access Key: (シークレットアクセスキーを入力)

Keychain からパスワードを求められるので、ログイン中のユーザーのパスワードを入力しましょう。因みにこのパスワードは変更できます (後述)

Keychain ファイルのパスワード入力画面。デフォルトではユーザーのパスワードになっている

aws-vault は一部の機能で ~/.aws/config の値を使う (後述) ので、このファイルに新たにディレクティブが作られます:

[profile test-profile]

また、登録したプロファイルは list (ls でも可) サブコマンドで確認できます:

Profile                  Credentials              Sessions
=======                  ===========              ========
test                     test                     -
foobar                   -                        -

この時、上記でいうと foobar の様な登録していないプロファイルも表示される事がありますが、プロファイルの一覧は単に ~/.aws/config に登録されたディレクティブに基づいており、 aws-vault でクレデンシャルを管理していない物も表示される為です。

クレデンシャルの利用: 1. AWS CLI 等のコンソールコマンドで利用

クレデンシャルの利用は一律で exec サブコマンドを使います。形式は aws-vault exec <利用するプロファイル名> <実行するコマンド> です、具体的には以下のようになります (実行時、パスワードの入力を求められるので入力しましょう):

$ aws-vault exec test-profile -- aws sts get-caller-identity
{
    "UserId": "AIDAYBFP3WB**********",
    "Account": "******113777",
    "Arn": "arn:aws:iam::******113777:user/issei-m"
}

aws sts get-caller-identity は、 API を呼び出す際の認証情報を出力するコマンドです。

上記のように、実際に実行したいコマンドのオプションを正しく読み込める様、コマンドの前には -- を置いておきましょう。

<実行するコマンド> は、 aws-vault がフォークする子プロセスで実行されます。 aws-vault exec はデフォルトでは保存されたクレデンシャルを直接使わず、代わりにこれによって (GetSessionToken 等を用いて) 取得した短い有効期限のセッショントークンを生成し、環境変数 (AWS_ACCESS_KEY_ID 等) を export した状態で実行コマンド用のプロセスをフォークします。

以下のように env コマンドを実行すると中身が見られます:

$ aws-vault exec test-profile -- env | grep AWS
AWS_VAULT=test-profile
AWS_ACCESS_KEY_ID=ASIATWFM3E********
AWS_SECRET_ACCESS_KEY=**************************************
AWS_SESSION_TOKEN=****************************************
AWS_SECURITY_TOKEN=****************************************
AWS_SESSION_EXPIRATION=2021-06-10T02:13:58Z

サブコマンドを指定しないと、bash や zsh 等、普段お使いのシェルにクレデンシャルが有効になった状態でログインができます:

$ av exec test-profile
$ aws sts get-caller-identity
{
    "UserId": "AIDAYBFP3WB**********",
    "Account": "******113777",
    "Arn": "arn:aws:iam::******113777:user/issei-m"
}

個人的には profile やクレデンシャルを export した状態で操作するのは事故りそうなのでオススメしませんが。

その他の exec の使い方

exec サブコマンドにはいくつかのオプションがあります。その一部を紹介します。

セッションの有効期限を長くしたい

先程出力した環境変数 AWS_SESSION_EXPIRATION を見ると分かりますが、 exec によって取得されたセッショントークンには有効期限があります。デフォルトでは 1 時間となっていますが、 --duration オプションを使うと延長する事ができます:

$ aws-vault exec test-profile --duration 6h -- ...

因みにセッションの期限が残ってる内は、 exec を何度実行しても以前に取得したものが使われるので初回よりも早く動作します。

保存されたクレデンシャルそのものを使いたい

セッショントークンによる一時的な認証では利用できない API (例: STS の殆どの API 等) ので保存されているマスタークレデンシャルを使いたいケースがあります。そう言う時は --no-session を使います:

$ aws-vault exec test-profile --no-session

保存されたままのセッションを経由したりしないのでキャッシュ等はされません。

IAM ユーザーではなく Role を使いたい

~/.aws/config を次のように編集します:

[profile test-power-user]
source_profile = test-profile
role_arn = arn:aws:iam::******113777:user/power-user

新たに専用のプロファイルのディレクティブを作り、 source_profile に AssumeRole する元のプロファイル (この場合既に使っている test-profile)、role_arn に対象の Role の ARN を入力します。

後は普通にこのプロファイルを指定して使うだけです:

$ aws-vault exec test-power-user -- ...

MFA を使いたい

以前、 MFA については以下のような記事を書きました。

aws-vault では MFA を使ったプロファイルでも簡単に扱う事ができます。こちらも ~/.aws/config を使います:

[profile test-profile]
mfa_serial=arn:aws:iam::******113777:mfa/issei-m

この通り MFA の SerialNumber (aws iam list-mfa-devices を使って取得する事が可能) を mfa_serial に登録するだけです。

後は Role の時と同様、普通に実行するだけです:

$ aws-vault exec test-profile -- aws sts get-caller-identity
Enter token for arn:aws:iam::******113777:mfa/issei-m:

aws-vault の通常時のパスワードとは別に、 MFA のコードの入力を求められるので、 MFA デバイスから払い出されたコードを入力すると、コマンドが実行されます。

クレデンシャルの利用: 2. マネジメントコンソールにログイン

login は aws-vault の中でも特に便利で気にっているコマンドです。これを使うと、そのプロファイルの権限でマネジメントコンソールにログインが可能です。(ID や パスワードが無くてもログインできます)

$ aws-vault login test-profile

実行するとデフォルトのブラウザが立ち上がり、マネジメントコンソールにログインされます。既にそのブラウザで別のアカウントでマネジメントコンソールにログインしているとエラーが表示されるので、予めログアウトしておきましょう。

また、期限がデフォルトだと 1 時間と短いので、必要に応じて設定して下さい:

$ aws-vault login test-profile --duration 3h

また、 --stdput オプションでブラウザを立ち上げる代わりにログインの URL を取得する事も可能です。

$ aws-vault login test-profile --stdout
https://signin.aws.amazon.com/federation?Action=login&Issuer=aws-vault&Destination=******************

セッションキーの削除

exec コマンドは通常、取得した一時的な認証キーを、クレデンシャル同様キーストア (今回は Keychain) に保存し、期限が切れるまでは使い回す様になっていますが、 clear サブコマンドを使うとキーストアから削除する事も可能です:

$ aws-vault clear
Cleared 1 sessions.

クレデンシャルのローテート (再生成)

rotate サブコマンドを使うと、キーストア (今回の場合 Keychain) に保存されているマスタークレデンシャルをローテート (再生成) して保存し直す事が可能です:

$ aws-vault rotate test-profile --no-session

一時的な認証キーでは IAM 関連のアクセスは制限されるので --no-session を付けるのが無難です。

クレデンシャルの削除

remove サブコマンドを使います:

$ aws-vault remove test-profile

パスワードを求められるので入力しましょう。尚、 ~/.aws/config から値は消えませんので必要に応じて手動で削除しましょう。

番外編: Keychain の保存場所とパスワードの変更

最後に番外編として、aws-vault の Keychain を使った際に保存先と、 Keychain ファイルのパスワード変更方法を共有して終わりたいと思います。

まず、 Keychain ファイルは ~/Library/Keychains/aws-vault.keychain-db になります。なのでこのファイル自体を移動させればインポート/エクスポートが簡単に行えます。
次はこれを開いてみましょう:

$ open ~/Library/Keychains/aws-vault.keychain-db

Keychain Access が開きます。左のメニューに有る “aws-vault” を右クリックすると現れるメニューでは、パスワードの変更や設定の変更を行う事が可能です:

Keychain メニュー

設定の変更では、ロックするまでの時間等を変更する事が可能です:

Keychain 設定変更

← 前の投稿

CentOS 7 から 8 へのアップグレード

次の投稿 →

Terraform で Amazon Lightsail 上に WordPress インスタンスを立てる

コメントを残す