2018年7月14日土曜日

AWSコンソールの貸し出しURL作成


フェデレーションユーザーに対して AWS マネジメントコンソール へのアクセスを許可する URL の作成(カスタムフェデレーションブローカー)」を参考にして、貸し出し用のAWSコンソールURLを作ってみます。

貸し出し用のURLでは、以下ができるようにします。
・認証不要。ただし、1時間(変更可能)しか使用できない。
・特定のロール(ReadOnlyなど)を割り当て、操作を制限する。

なお、URL作成時には、aws-cli を使用し、MFA必須とします。


1. URL作成用のIAMユーザを作成


「貸し出し用URL」を作成するIAMユーザを用意します。
今回作成するIAMユーザの名称は、"ops" とします。

[アクセス権限]タブで、[インラインポリシーの追加]をクリックし、インラインポリシーを作成します。
貸し出しURL作成に必要な権限だけ付与しています。


[認証情報]タブで、[MFAデバイスの割り当て]を実施します。
また、[アクセスキーの作成]ボタンでアクセスキーを作成します。


アクセスキーは、「貸し出しURL」を作成するマシンに設定します。
今回は、以下のようにしています。
[root@centos701 ~]# cat ~/.aws/credentials
[default]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>

[ops]
aws_access_key_id = <上記で作成したアクセスキー>
aws_secret_access_key = <上記で作成したシークレットアクセスキー>

[root@centos701 ~]# cat ~/.aws/config
[default]
output = text
region = us-east-1

[profile ops]
output = text
region = us-east-1


2.AWSコンソールに割り当てるロールを作成


今回は、EC2の参照権限しかないロールを作成します。
今回作成するロールの名称は、"EC2ReadOnly" とします。
[アクセス権限]タブで AmazonEC2ReadOnlyAccess ポリシーを割り当てます。


[信頼関係]タブで、[信頼されたエンティティ]に上記1で作成した opsユーザを指定し、MFA必須にします。
[信頼関係の編集]ボタンをクリックして、以下のように設定します。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::12345678:user/ops"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Null": {
          "aws:MultiFactorAuthAge": "false"
        }
      }
    }
  ]
}


ちなみに、[最大 CLI/API セッション期間]に表示されてる時間が、AWSコンソールを操作できる最大時間になります。この時間を過ぎると自動的にログアウトします。


3.URL作成用のスクリプトを作成


今回作成したスクリプトは以下のとおり。
ファイル名は awsurl.sh とします。

#!/bin/bash

PROF=ops
SERIAL_NUMBER=arn:aws:iam::12345678:mfa/${PROF}
AWS_FED_URL=https://signin.aws.amazon.com/federation
AWS_CONSOLE_URL=https://console.aws.amazon.com/
DURATION=3600 #sec

function urlencode
{
    echo "$1" \
        | python -c 'import sys,urllib; sys.stdout.write(urllib.quote_plus(raw_input()))'
}

if [ $# -ne 2 ]; then
    echo "usage: $(basename $0) <role name> <code>"
    exit 1
fi

role=$1
code=$2

arn=$(aws iam list-roles \
    --query "Roles[?RoleName == '${role}'].Arn" \
    --profile ${PROF} \
    --output text)

if [ "${arn}" == "" ]; then
    echo "${role} is not found."
    exit 1
fi

key=$(aws sts assume-role \
    --role-arn "${arn}" \
    --role-session-name OneTimeSession \
    --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
    --profile ${PROF} \
    --serial-number ${SERIAL_NUMBER} \
    --token-code ${code} \
    --output text)

access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$1)}')
secret_access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$2)}')
session_token=$(echo "${key}" | awk -F"\t" '{printf("%s",$3)}')

if [ "${access_key}" == "" ]; then
    echo "assume-role failed."
    exit 1
fi

json="{\"sessionId\":\"${access_key}\",\"sessionKey\":\"${secret_access_key}\",\"sessionToken\":\"${session_token}\"}"

token=$(curl -s "${AWS_FED_URL}?Action=getSigninToken&SessionDuration=${DURATION}&Session=$(urlencode ${json})" \
    | jq -r .SigninToken)

if [ "${token}" == "" ]; then
    echo "get signin token failed."
    exit 1
fi

url="${AWS_FED_URL}?Action=login&Issuer=&Destination=$(urlencode ${AWS_CONSOLE_URL})&SigninToken=$(urlencode ${token})"

echo ${url}

exit 0

4.動作確認


EC2の参照しかできないAWSコンソールのURLを作ってみます。
上記3で作成したスクリプトの引数に、「ロール名」、「opsユーザ用MFAのパスコード」を指定して実行すると、URLが表示されます。
[root@centos701 awscli]# ./awsurl.sh EC2ReadOnly 160335
https://signin.aws.amazon.com/federation?Action=login&Issuer=&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&SigninToken=RHe2_m5aLBqK0Ci7_XXmp05OSMj0wGiFp1el48SI-qqR8WZV3qqTvYvBZQw7UrEHUUa5BOaH9IderXxzwtkicg9LGEJO0239ih8psYfidXoC_QHTeW_7DKBTIHGoU1NlU-xYXhcmDbidSE8LKZS4ZqjI0uxbzLuTnCU6iVHUdPAt4iqsLXpKa4oPTfUAexY52MnBZhZElNxXK4DVOyNEkCYWTUNisR9ufxAyf3GoC1f-7UbE4Dt_vdYkKOlED4k7FAaoUMo5OazE0mr-IJiYS7rnwYVUMcVnd7y-01CarUU4OdFt8rIiPfs6UprHBbpCOCqJdFf4jXFUy4olKdLtnorh6waDfO8wSmyQlPHu2P0QJDTzsvPekux06dDPzyRgEk3Uw9bHOxX6DpRO4Sqgev9t09t7VH5fkNshUZbF8SB2m4J7vNcWG7v0YDGGmdNd2QWKI47yZ1luN_C9MQS84IePpGfGicK9Uoda-mjXWvBAVBxA-4uA3qSzUsb0bLpXNAEx_lo14XY2p-I9RgLM_i3DDvx2WP6_kg9L0JZrTVU4zmTF19bORYPde6w854gTlpUXWKVWVMwqg7Tid-T2l7AYapkduA7KYLcBd2m0-wIqBVcc6liZYUEv7bs6gmobwH3vaLlCgTHF7x98JXlF5B0AT845_FP-Ng-BJwiKmpcyIg50_8f4W-V3vl7zRq0n9VKED53jJBYmABRuDc_QRoLUrW7Qa3qBQzMJ6Gq7-A0_CkhL3vBM8ax0I_WHcxkICCIUegh9hoIbsg41O9RJZkwsXCM3BsmTasKta_vosHdPYWzNw5_Dy2otHEUzM88s

このURLをブラウザにペーストして、AWSコンソールを開きます。
認証なしで下図にように画面が表示されます。
表示されるログイン名は、[EC2ReadOnly/OneTimeSession] です。
ロール名と、スクリプトの assume-role(awscli) で指定したセッション名が表示されています。


EC2は、下図のように参照できます。


S3を参照しようとすると、権限がないので、エラーになります。