AssumeRoleを連続でスイッチし、同じコマンドをひたすら実行する際、コマンドごとにMFA認証が行われてとても面倒でした。
そこで認証をスキップする方法を探したものの、なかなか良い解決策が見つからず苦戦したためメモ書きします。
以下のようにコマンドごとにMFA認証が行われるのを回避するが本記事の目的です。
aws s3 ls --profile target-assume-1 --no-cli-pager
Enter MFA code for arn:aws:iam::111111111111:mfa/<user_name>:
#--- コマンド実行結果 ---#
aws s3 ls --profile target-assume-2 --no-cli-pager
Enter MFA code for arn:aws:iam::111111111111:mfa/<user_name>:
#--- コマンド実行結果 ---#
aws s3 ls --profile target-assume-3 --no-cli-pager
Enter MFA code for arn:aws:iam::111111111111:mfa/<user_name>:
#--- コマンド実行結果 ---#
解決方法
~/.aws/credentials
ファイルを次のように修正したあと、セッショントークンを生成(※後述)することでMFA認証を一定時間省略できます。
[default]
aws_access_key_id = xxxxxxxxxxxx
aws_secret_access_key = yyyyyyyyyyyyy
[target-assume-1]
role_arn = arn:aws:iam::333322221111:role/<role_name>
mfa_serial = arn:aws:iam::999988887777:mfa/<IAMユーザーID>
source_profile = default
[target-assume-2]
role_arn = arn:aws:iam::444422221111:role/<role_name>
mfa_serial = arn:aws:iam::999988887777:mfa/<IAMユーザーID>
source_profile = default
# 以下target-assume-3、4、5 ・・・と続く
[default]
aws_access_key_id = xxxxxxxxxxxx
aws_secret_access_key = yyyyyyyyyyyyy
[target-assume-1]
role_arn = arn:aws:iam::333322221111:role/<role_name>
# mfa_serial の定義を消す
# source_profile = default をdefault-mfaに書き換える
source_profile = default-mfa
[target-assume-2]
role_arn = arn:aws:iam::444422221111:role/<role_name>
# mfa_serial の定義を消す
# source_profile = default をdefault-mfaに書き換える
source_profile = default-mfa
# 以下target-assume-3、4、5 ・・・と続く
# default-mfaを後述するシェルスクリプトで自動生成する
[default-mfa]
aws_access_key_id = aaaaaaaaa
aws_secret_access_key = bbbbbbbbb
aws_session_token = cccccccccc
修正内容としては、credentialsファイルの各target-assume-xで定義されている mfa_seriaの設定を削除します。
次に、default
プロファイルの設定を元にdefault-mfa
プロファイルを生成し、その内容をcredentialsファイルに記載します。
default-mfa
は、MFAなどの情報を元にセッショントークンを生成し、AWSの認証を一定時間保持します。マニュアル
デフォルトで12時間セッションが保持されます。マニュアル)
これを各target-assume-xに読み込ませることで、各プロファイルのMFA認証を省略できます。
default-mfa
については後述するシェルスクリプトを実行することで生成され、credentialsファイルに登録してくれます。
セッショントークンを生成スクリプト
以下はセッショントークンを生成するシェルスクリプトです。
このシェルスクリプトについてはこちらの記事を参考にさせて頂きました。(大変助かりました...セッショントークンを生成するシェルスクリプト<(_ _)>
)
スクリプトの実行には、jqコマンドの利用が必要となるため、事前にインストールしておきます。MACの場合は次のコマンドで取得可能です。
brew install jq
#!/bin/bash
# 自分の環境に合うように変数の値を設定
PLOFILE_NAME=default
ACCOUNT_ID=999988887777
IAM_USER_ID=username
# セッショントークン等の生成
SESSION_INFO=$(aws --profile $PLOFILE_NAME sts get-session-token --serial-number arn:aws:iam::$ACCOUNT_ID:mfa/$IAM_USER_ID --token-code $1 --output json)
if [ $? -ne 0 ]; then
exit 1
fi
# 生成された情報の整理
MFA_ACCESS_KEY=$(echo $SESSION_INFO | jq -r '.Credentials.AccessKeyId')
MFA_SECRET_ACCESS_KEY=$(echo $SESSION_INFO | jq -r '.Credentials.SecretAccessKey')
MFA_SESSION_TOKEN=$(echo $SESSION_INFO | jq -r '.Credentials.SessionToken')
MFA_EXPIRATION=$(echo $SESSION_INFO | jq -r '.Credentials.Expiration')
# credentialsファイルに設定するプロファイル名
PROFILE_NAME=default-mfa
# credentialsファイルへ設定を登録
aws --profile $PROFILE_NAME configure set aws_access_key_id $MFA_ACCESS_KEY
aws --profile $PROFILE_NAME configure set aws_secret_access_key $MFA_SECRET_ACCESS_KEY
aws --profile $PROFILE_NAME configure set aws_session_token $MFA_SESSION_TOKEN
echo "successfully. profile: $PROFILE_NAME, expiration: $MFA_EXPIRATION"
シェルスクリプトは次のように実行します。
$ # 下記123456 はMFA code
$ mfa_token_register.sh 123456
successfully. profile: default-mfa, expiration: 2020-03-05 11:22:01
実行後にcredentialsを確認すると、default-mfa
が新規作成(または上書き)されます。
[default-mfa]
aws_access_key_id = aaaaaaaaa
aws_secret_access_key = bbbbbbbbb
aws_session_token = cccccccccc
これで12時間の間、MFA認証がスキップされるようになりました。
aws s3 ls --profile target-assume-1 --no-cli-pager
#--- コマンド実行結果 ---#
aws s3 ls --profile target-assume-2 --no-cli-pager
#--- コマンド実行結果 ---#
aws s3 ls --profile target-assume-3 --no-cli-pager
#--- コマンド実行結果 ---#
aws s3 ls --profile target-assume-4 --no-cli-pager
#--- コマンド実行結果 ---#