この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWSチームのすずきです。
AWSのマネジメントコンソールのセッション時間、デフォルトの1時間から12時間に延長するため、 セッション時間を12時間に延長したコンソールURLをCLIで作成する機会がありました。
MFAの必須化と接続元IPを限定し、認証情報の不正利用に備えたIAMロールの設定とあわせて紹介させていただきます。
実行環境
OS
MaxOS環境を利用しました。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.6
BuildVersion: 18G103
パッケージ
「awscli」「jq」は事前にインストール済みのものを利用しました。
$ aws --version
aws-cli/1.16.253 Python/3.7.0 Darwin/18.7.0 botocore/1.12.243
$ jq --version
jq-1.5
AWS設定
IAM
スイッチ元
STS(assume-role)権限を付与、MFAデバイスを割り当てたIAMユーザを利用しました。
- アクセス権限
- 認証情報
- 発行したアクセスキー、CLI実行環境のcredentialsとして登録しました。
$ cat ~/.aws/credentials
[default]
aws_access_key_id = aaa<略>
aws_secret_access_key = bbb<略>
スイッチ先
今回、マネジメントコンソールで利用するロールは、 AWS管理ポリシー「CloudWatchReadOnlyAccess」をアタッチ。 最大 CLI/API セッション期間 は 「12時間」 に延長したものを用意しました。
信頼関係の設定は、スイッチ元は先にアクセスキーを用意したIAMユーザに限定。MFAを必須とし、特定IP以外からの利用を禁止する設定としました。
- ポリシードキュメント例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:user/EXAMPLEIAMUSERNAME"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::000000000000:user/EXAMPLEIAMUSERNAME"
},
"Action": "sts:AssumeRole",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"103.15.250.0/24",
"12.148.72.0/23"
]
}
}
}
]
}
スクリプト
get-consol-login-url.sh
#!/bin/bash
MFA_ARN="$1"
ROLE_ARN="$2"
MFA_CODE="$3"
if [ -z ${MFA_CODE} ]; then
echo 'No MFA one time pass code'
echo "MFA_ARN: ${MFA_ARN}"
exit
fi
SESSION_DURATION=43200
CUR_TIME=`date '+%Y%m%d%H%M%S'`
# assume-role
TMP1=`aws sts assume-role --role-arn ${ROLE_ARN} --role-session-name cli-${CUR_TIME} --duration-seconds ${SESSION_DURATION} --serial-number ${MFA_ARN} --token-code ${MFA_CODE}`
# security credentials (URL encoded)
TMP2=`echo ${TMP1} |jq -r '"%7B%22sessionId%22%3A%22"+.Credentials.AccessKeyId+"%22%2C%22sessionKey%22%3A%22"+.Credentials.SecretAccessKey+"%22%2C%22sessionToken%22%3A%22"+.Credentials.SessionToken+"%22%7D"' | sed -e "s/=/%3D/g"|sed -e "s/+/%2B/g"|sed -e "s/\//%2F/g"`
# URL for Get SigninToken
TMP3=`echo "https://signin.aws.amazon.com/federation?Action=getSigninToken&SessionType=json&Session=${TMP2}"`
# Get SigninToken
TMP4=`curl -s ${TMP3} | jq -r .SigninToken`
# URL for Console Login
echo "https://signin.aws.amazon.com/federation?Action=login&Issuer=cm-demo&Destination=https%3A%2F%2Fap-northeast-1.console.aws.amazon.com%2Fconsole&SigninToken=${TMP4}"
- 実行例
./get-consol-login-url.sh arn:aws:iam::000000000000:mfa/<MFA名> arn:aws:iam::111111111111:role/<ロール名> <MFA_CODE>
- 出力例
https://signin.aws.amazon.com/federation?Action=login&Issuer=cm-demo&Destination=https%3A%2F%2Fap-northeast-1.console.aws.amazon.com%2Fconsole&SigninToken=<略>
利用例
生成されたURLをブラウザに登録する事で、指定したロール権限で、12時間までセッション時間を延長したマネジメントコンソールの利用が可能となります。
Mac OSX環境であれば「open」を利用して、マネジメントコンソールログイン済みのブラウザを開く事も可能です。
./get-consol-login-url.sh arn:aws:iam::000000000000:mfa/<MFA名> arn:aws:iam::111111111111:role/<ロール名> <MFA_CODE> | xargs open
自動更新を有効にしたCloudWatchのグラフ表示、1時間以上セッションが切れる事なく表示される事を確認できました。
- 接続後1時間30分経過したCloudWatch表示例
詳細解説
コンソールログイン用のURL発行は、以下ドキュメントの内容をCLIで実施しています。
その手順を紹介します。
フェデレーションユーザーに対して AWS マネジメントコンソール へのアクセスを許可する URL の作成 (カスタムフェデレーションブローカー)
AssumeRole
MFA情報と有効期限を12時間(43200秒)を指定して、一時認証情報を取得します。
MFA_ARN='arn:aws:iam::000000000000:mfa/<MFA名>'
ROLE_ARN='arn:aws:iam::111111111111:role/<ロール名>'
MFA_CODE="00000"
SESSION_DURATION=43200
TMP1=`aws sts assume-role --role-arn ${ROLE_ARN} --role-session-name cli --duration-seconds ${SESSION_DURATION} --serial-number ${MFA_ARN} --token-code ${MFA_CODE}`
echo ${TMP1} |jq .
- 実行結果
{
"Credentials": {
"AccessKeyId": "aaaa<略>",
"SecretAccessKey": "bbbbbb<略>",
"SessionToken": "cccccccc<略>",
"Expiration": "2019-10-08T02:41:10Z"
},
"AssumedRoleUser": {
"AssumedRoleId": ""dddd<略>:cli",
"Arn": "arn:aws:sts::111111111111:assumed-role//<ロール名>/cli"
}
}
セキュリティ認証情報の加工
AWS フェデレーションエンドポイント用にセキュリティ認証情報を加工します。
「jq」と「sed」を利用したURLエンコード方法については、下記ブログ記事を参考にさせて頂きました。
TMP2=`echo ${TMP1} |jq -r '"%7B%22sessionId%22%3A%22"+.Credentials.AccessKeyId+"%22%2C%22sessionKey%22%3A%22"+.Credentials.SecretAccessKey+"%22%2C%22sessionToken%22%3A%22"+.Credentials.SessionToken+"%22%7D"' | sed -e "s/=/%3D/g"|sed -e "s/+/%2B/g"|sed -e "s/\//%2F/g"`
echo ${TMP2}
%7B%22sessionId%22%3A%22<略>%22%2C%22sessionKey%22%3A%22<略>%22%2C%22sessionToken%22%3A%22<略>
サインイン用のトークン
加工したセキュリティ認証情報を利用して、AWS フェデレーションエンドポイントよりサインイン用のトークンを取得します。
TMP3=`echo "https://signin.aws.amazon.com/federation?Action=getSigninToken&SessionType=json&Session=${TMP2}"`
TMP4=`curl -s ${TMP3} | jq -r .SigninToken`
echo ${TMP4}
Ek1wa-_<略>__<略>
ログイン用URL
トークンを含む、マネジメントコンソールログイン用のURL(15分有効) を生成します。
echo "https://signin.aws.amazon.com/federation?Action=login&Issuer=cm-demo&Destination=https%3A%2F%2Fap-northeast-1.console.aws.amazon.com%2Fconsole&SigninToken=${TMP4}"
まとめ
Amazon Athena、AWS Lambda など、AWSのマネジメントコンソールで操作する場合、 1時間のセッション切れにより作業内容が失われる事がありましたが、 AssumeRole を利用した コンソールURL を利用する事で最大12時間のセッション維持した利用が可能になります。
今回AssumeRoleで利用するIAMロールで、MFA、接続元IP制限を行う事で不正利用対策としていますが、 強い権限を持つIAMロールでのコンソールURL発行は避け、必要最小限のロールでの利用をおすすめします。