【AWS】ベストプラクティスに準拠してアクセスキーを利用したい

こんにちは。SCSK渡辺(大)です。

人生初のIDEとしてCloud9を使っていたのですが、とある理由からVisual Studio Codeを使いたくなりました。
Visual Studio CodeからAWSリソースにアクセスするには、アクセスキーが必要になります。

そこで今回は、ベストプラクティスに準拠してアクセスキーを利用する方法を考えてみました。

当記事はアクセスキーの漏洩を防止するという内容ではなく、万が一にもアクセスキーが漏洩した場合に備えた内容です。

アクセスキーが漏洩した場合のリスク

一例ですが以下が挙げられます。

  • 不正利用により予期せぬ多額の請求
  • 顧客情報などの情報漏洩
  • リソース削除によるサービス停止

IAMでのセキュリティのベストプラクティス

ベストプラクティスを確認します。

参考:IAMでのセキュリティのベストプラクティス

MFAを強制したい

Visual Studio CodeからAWSリソースにアクセスするためには、ローカル環境に導入したAWSクレデンシャルファイルにアクセスキーとシークレットキーを明記する必要があります。
ただし、それだけではMFA強制にすることは出来ません。

AWS CLIでMFA強制にするにはひと手間必要です。

 

このひと手間が面倒だと感じたのでBashシェルスクリプトにしました。

■get-session-token.sh

#!/bin/bash

# credentialsを削除し、credentials.bkをcredentialsとしてコピー
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
if [ -f ~/.aws/credentials.bk ]; then
rm -f ~/.aws/credentials
cp ~/.aws/credentials.bk ~/.aws/credentials
echo "AWS credentials have been reset from backup."
else
echo "Backup file (credentials.bk) not found. Please ensure it exists."
exit 1
fi

# 現在の AWS 設定を確認
echo "Current AWS configuration:"
aws configure list

# MFAトークンコードの入力を求める
read -p "Enter your MFA token code: " token_code

# AWS STS get-session-tokenを実行
session_token=$(aws sts get-session-token --serial-number arn:aws:iam::[アカウントID]:mfa/[MFA名] --token-code $token_code)

if [ $? -ne 0 ]; then
echo "Failed to get session token. Please check your AWS configuration and MFA token."
exit 1
fi

# クレデンシャルを環境変数にエクスポート
export AWS_ACCESS_KEY_ID=$(echo $session_token | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $session_token | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $session_token | jq -r '.Credentials.SessionToken')

# AWSクレデンシャルファイルを更新
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set aws_session_token $AWS_SESSION_TOKEN

echo "AWS credentials have been updated."

# 更新された AWS 設定を確認
echo "Updated AWS configuration:"
aws configure list

# 現在のロールを表示
echo "Current role is..."
aws sts get-caller-identity --query "[Account, Arn]"

if [ $? -ne 0 ]; then
echo "Failed to get caller identity. Please check your AWS configuration."
exit 1
fi

 

ついでに、スイッチロールもBashシェルスクリプトにしました。

■change-role.sh

#!/bin/bash

# 現在の認証情報を表示
echo "Current identity:"
aws sts get-caller-identity

# ユーザーからアカウントIDとロール名を入力してもらう
read -p "Enter the AWS account ID: " account_id
read -p "Enter the role name: " role_name

# role assumeを実行
echo "Assuming role..."
role_credentials=$(aws sts assume-role --role-arn "arn:aws:iam::${account_id}:role/${role_name}" --role-session-name "${role_name}")

# 環境変数を設定
export AWS_ACCESS_KEY_ID=$(echo $role_credentials | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $role_credentials | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $role_credentials | jq -r '.Credentials.SessionToken')

# 新しい認証情報を確認
echo "New identity after assuming role:"
aws sts get-caller-identity

 

設計

方針

  • IAMユーザーにはIAMロールへスイッチ(AssumeRole)できる権限のみを付与する
  • IAMロールの信頼ポリシー上でも、IAMユーザーからのスイッチにはMFA強制にする
  • IAMロールにはAdministratorAccessを付与する

構成図

 

準備

AWS側の作業
  • IAMユーザーを作成する
    • 自分のMFA設定、アクセスキー作成、下記IAMロールへのスイッチ、のみ許可する
  • IAMロールを作成する
    • 信頼ポリシーは上記IAMユーザーかつMFA強制でスイッチ許可する
    • AdministratorAccessを付与する
  • IAMユーザーでAWSマネジメントコンソールにログインする
    •  MFA設定する
    • アクセスキーを作成する
ローカル環境側の作業
  • Visual Studio Codeをインストールする
  • AWS CLIを導入する
    • Visual Studio Codeで「aws –version」と打ってバージョンが表示されることを確認する
  • jqを導入ダウンロードする
    • Bashシェルスクリプトで使う
    • 公式サイトからダウンロードした.exeファイルをjq.exeにリネーム後、所定の場所(WindowsならC:\WINDOWS\system32\jq.exe)に移動する
    • Visual Studio Codeで「jq –version」と打ってバージョンが表示されることを確認する
  • AWSクレデンシャルファイルを修正する
    • Visual Studio Codeで「aws config」と打ち、アクセスキー、シークレットキーを入力する(その他は任意)
  • 前述のBashシェルスクリプトを作成する
  • credentialsをコピーしてcredentials.bkを作成する

実行結果

1.BashシェルスクリプトでMFA認証します。

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ ./get-session-token.sh
AWS credentials have been reset from backup.
Current AWS configuration:
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************XXXX shared-credentials-file
secret_key ****************XXXX shared-credentials-file
region ap-northeast-1 config-file ~/.aws/config
Enter your MFA token code: 999999
AWS credentials have been updated.
Updated AWS configuration:
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************XXXX env
secret_key ****************XXXX env
region ap-northeast-1 config-file ~/.aws/config
Current role is...
[
"[アカウントID]",
"arn:aws:iam::[アカウントID]:user/[IAMユーザー名]"
]

 

2.MFA認証したものの、IAMユーザーには殆ど権限ないことを確認します。
特に、IAMロールのリストが表示できないことは重要です。
表示できてしまうと、アクセスキーの不正利用者が全てにスイッチロールすることを試すことが出来てしまうためです。

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ aws iam list-roles

An error occurred (AccessDenied) when calling the ListRoles operation: User: arn:aws:iam::[アカウントID]:user/[IAMユーザー名] is not authorized to perform: iam:ListRoles on resource: arn:aws:iam::[アカウントID]:role/ because no identity-based policy allows the iam:ListRoles action

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ aws s3 ls

An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:iam::[アカウントID]:user/[IAMユーザー名] is not authorized to perform: s3:ListAllMyBuckets because no identity-based policy allows the s3:ListAllMyBuckets action

 

3.IAMロールにスイッチロールします。

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ source ./change-role.sh
Current identity:
{
"UserId": "[UserId]",
"Account": "[アカウントID]",
"Arn": "arn:aws:iam::[アカウントID]:user/[IAMユーザー名]"
}

Enter the AWS account ID: [アカウントID]
Enter the role name: [IAMロール名]
Assuming role...
New identity after assuming role:
{
"UserId": "[UserId]:[IAMロール名]",
"Account": "[アカウントID]",
"Arn": "arn:aws:sts::[アカウントID]:assumed-role/[IAMロール名]/[セッション名]"
}

 

4.IAMロールにはAdministratorAccessが付与されているので、コマンドが受け付けられました。

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ aws iam list-roles
{
"Roles": [
{
"Path": "/service-role/",
~~(中略)~~
"AssumeRolePolicyDocument": {
^C

XXXXX@XXXXXX XXXXXX ~/work/awsTest
$ aws s3 ls
yyyy-mm-dd hh:mm:ss [S3バケット名]

 

まとめ

思ったより大変でした。
調査の途中、AWS Toolkitとごっちゃになってしまいました…

余談ですが、いまはAWS AmplifyとCDKをマイペースで勉強中です。
当記事もそうですが、アウトプットすることは自分の勉強になるので、次はAmplifyかCDKについての記事を投稿してみたいと思っています。

タイトルとURLをコピーしました