ちょっと話題の記事

AWS Vaultで端末内のAWSアクセスキー平文保存をやめてみた

より安全にアクセスキーが保管できます
2021.06.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWSアクセスキーセキュリティ意識向上委員会って何?

昨今、AWSのアクセスキーを漏洩させてしまうことが原因でアカウントへの侵入を受け、
多額の利用費発生・情報漏洩疑いなど重大なセキュリティ事案が発生するケースが実際に多々起きています。

そこで、アクセスキー運用に関する安全向上の取組みをブログでご紹介する企画をはじめました。

アクセスキーを利用する場合は利用する上でのリスクを正しく理解し、
セキュリティ対策を事前に適用した上で適切にご利用ください。

AWS Valutとは

AWSのアクセスキー/シークレットキーを安全に保存・利用するためのOSSソフトウェアです。
AWS CLIだけではなく、boto3等AWS SDKを用いた開発、
Terraform等のサードパーティアプリケーションでも利用することが出来ます。

AWS VaultはIAM認証情報をOSのキーストアに保存し、認証情報の利用時にはSTSにて一時的な認証情報を取得した上でシェルやアプリケーションに引き渡します。

生のIAM認証情報が利用者やアプリケーションに公開されなくなるので、 ヒューマンエラーによる認証情報の漏洩リスクや悪意のあるアプリケーションなどから認証情報を保護できます。
(万一漏洩が発生しても、生のアクセスキーではなくSTSから取得した一時的な認証情報なので一定時間経過でexpireされます)

macOS, Windows, Linux, FreeBSD等多くのOSに対応しています。
今回はmacOSで使ってみました。

やってみる

インストール

Homebrewでインストールできます。

$ brew install --cask aws-vault

IAMユーザアクセスキーの登録

classmethod というプロファイル名でアクセスキーとシークレットキーを登録してみます。
既存の~/.aws/credentials, ~/.aws/config は特に上書きされないので、気軽に試してみてください。

$  aws-vault add classmethod
Enter Access Key ID: AKIAXA25HOGEFUGAPIYO
Enter Secret Access Key: 
Added credentials to profile "classmethod" in vault

シークレットキーを入力してエンターを押すと、OSのキーチェーンにパスワードの登録が求められます。

登録が終わったら、対象のIAMユーザがAWS Vaultに登録されていることがわかりました。

$ aws-vault ls
Profile                  Credentials              Sessions                 
=======                  ===========              ========                 
classmethod              classmethod              -

aws-vaultを使ってAWS CLIを実行するには、以下のようにコマンドを実行します。

$ aws-vault exec <プロファイル名> -- <AWS CLIコマンド>

そうすると、キーチェーンからパスワードが求められ、認証情報が利用できます。
※ その後一定時間、コマンドを実行してもキーチェンのパスワードを聞かれなくなります

$ aws-vault exec classmethod -- aws sts get-caller-identity
{
    "UserId": "AIDAHOGEFUGAPIYOYO",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/<IAMユーザ名>"
}

aws-vaultコマンドにより、環境変数に一時的な認証情報がセットされてコマンドを実行できるようです。

$  aws-vault exec classmethod -- env | grep AWS
AWS_VAULT=classmethod
AWS_ACCESS_KEY_ID=ASIA%%
AWS_SECRET_ACCESS_KEY=%%%
AWS_SESSION_TOKEN=%%%
AWS_SECURITY_TOKEN=%%%
AWS_SESSION_EXPIRATION=2021-05-31T01:51:29Z

CloudTrailからも、先頭4文字が"ASIA"の、生のアクセスキーではない一時的な認証情報を用いてAPI呼び出しをしていることが確認できました。
※先頭4文字が"ASIA"のアクセスキーは、一時的な認証情報であることを示します。

参考: IAM 識別子 - AWS Identity and Access Management

スイッチロール先の登録

IAMユーザからスイッチロールをしたい場合は、~/.aws/config の編集が必要です。
(aws-vaultは、~/.aws/credentials を利用しません)

書式は色々なパターンがありますが、私の場合はスイッチロール先が複数あるのでファイルの記載をスッキリさせるため共通の "common" profileを作成し、各ロールにincludeさせました。

$ cat ~/.aws/config
[profile common]
source_profile = classmethod
region=ap-northeast-1
output=json
mfa_serial=arn:aws:iam::123456789012:mfa/<IAMユーザ名>
role_session_name=cm-kato.saori

[profile myrole1]
include_profile=common
role_arn=arn:aws:iam::999999999999:role/<ロール名>

[profile myrole2]
include_profile=common
role_arn=arn:aws:iam::888888888888:role/<ロール名>

スイッチロール先のprofileを指定してAWSコマンドを実行すると、MFAとキーチェーンのパスワードを問われました。
キーチェーンのパスワードを入力すると、以下のようにロールの一時的な認証情報を利用してコマンドを実行することができます。
※ その後一定時間、コマンドを実行してもキーチェンのパスワード/MFAを聞かれなくなります

$ aws-vault exec myrole1 -- aws sts get-caller-identity
Enter token for arn:aws:iam::123456789012:mfa/<IAMユーザ名> XXXXXX
{
    "UserId": "AROAHOGEFUGAPIYOXXXX:cm-kato.saori",
    "Account": "999999999999",
    "Arn": "arn:aws:sts::999999999999:assumed-role/<role-name>/cm-kato.saori"
}

AWS SDKを利用したコードの実行

ローカル開発時にアクセスキーをハードコーディングする必要はありません。
ローカルでも本番で利用するコードと同じように開発することができます。

簡単なサンプルコードを書いてみました。

import boto3

client = boto3.client('sts')
try:
    response = client.get_caller_identity()
except Exception as e:
    print(e)
else:
    print('success')

AWS CLIコマンドと同じく、aws-vault execコマンドにより環境変数に設定された認証情報を利用することで実行可能でした。

$ aws-vault exec myrole1 -- python sample.py
Enter token for arn:aws:iam::123456789012:mfa/<IAMユーザ名>: XXXXXX
success

Terraform等サードパーティツールも、環境変数上の認証情報を読めるツールであれば同様に利用できそうです。

[Terraform CLI]MFA認証を使ったAssumeRole。AWSVaultで解決 | DevelopersIO

キーのローテーション

アクセスキーをローテーションするコマンドがあります。
コマンドひとつでできるので、定期的にアクセスキーをローテーションするハードルが低くなります。

$ aws-vault rotate private --no-session
Rotating credentials stored for profile 'private' using master credentials (takes 10-20 seconds)
Creating a new access key
Created new access key ****************TIZG
Deleting old access key ****************CL3Z
Deleted old access key ****************CL3Z
Finished rotating access key

AWSコンソールへのログイン

コマンドを叩いてキーチェーンのパスワードを入力すると、ブラウザが立ち上がりAWSマネジメントコンソールにログインできます。

CLI経由でマネコンにログインできるのは便利なので、重宝しそうです。

$ aws-vault login myrole1
Enter token for arn:aws:iam::123456789012:mfa/<IAMユーザ名>: XXXXXX
# ブラウザでマネコンが立ち上がる

おわりに

AWS-Vaultでより安全にアクセスキーを保管することができるようになりました。 キー漏洩が心配な方は是非試してみてください!