amareloのブログ(仮)

IT系勉強会で感じた想いや知見をメインに書いていきます。

JAWS-UG CLI専門支部 #159R IAM入門 参加レポート

6/22(月)、JAWS-UG CLI専門支部 #159R IAM入門に参加しました。今回もハンズオンの感想と学んだコマンドについて書きます。

目次

イベントページ

jawsug-cli.connpass.com

ハンズオンでやったこと

以下の通りです。事前準備として、Cloud9上にハンズオン環境を構築しました。 ハンズオンでは、Cloud9のターミナルでコマンド実行しました。

IAMとは

  • IAMマネジメントコンソールレベルでは対になっている。
  • API単位ではIAMとSTSが密接な関係にある
  • AWSアカウントはメールアドレスに紐づいた親アカウント
    • 初期設定が終了したら封印して二度と使うことはないようにしておく
  • 昔はAWSアカウントですべてのリソースを操作していた。
  • 過大な権限による弊害を避けるためにIAMが生まれた
    • 適切な権限の分割が目的
    • 現行のバージョンは2012年10月
  • AWSを真に理解するとは

    • AWS APIの働きを理解すること
      • IAMを知ることは、AWSAPIアクションとの付き合い方を知ること
      • AWSの学習、設計、実装は、IAMにはじまりIAMに終わる
      • IAMが分からない人はAWSを分かっていない人
  • IAMのサービス概要

    • AWSの利用はAWSリソースのAPIを実行すること
    • 外部リソース、AWSリソース、利用者からのアクセスで何のサービスを制限するのかを定義するのがIAM
    • ユーザやグループは人とサービスをつなぐもの
    • ロールはAWSリソース同士をつなぐもの
  • ユーザ・グループとロールの認証上の違い

    • ユーザ・グループは利用者や外部リソースからの認証情報が必要
      • ユーザプロファイルとAPIアクセスキー
      • MFAによる保護
    • ロールはAWSリソースからの制御で認証情報が不要
      • (6/27追記)厳密には裏側でテンポラリークレデンシャルの生成と更新が自動でされている。
  • IAM設計における2つの戦略観点

    • 防御戦略
      • いかにクレデンシャルを抜かれないようにするか
      • クレデンシャルを悪用される状況が最も危険
      • これらをなるべく使わない
      • IAMロールをなるべく使う
        • EC2やCloud9を作業環境として使わないときは落とす
    • 権限戦略
      • ユーザは最低限&分割
      • 複数の場所で同一ユーザを使わない
      • 最小権限の原則(一番大事)
        • ポリシは使い捨て
        • 人とリソースの両面からポリシを考える
        • 小さなポリシを組み合わせて適用する
          • IAMポリシは1つの対象に対して10ポリシを適用できる
  • IAM設計上の戦術

    • クレデンシャルはMFAで保護する
    • アクセスキーは2つ作成できるので自動更新できるようにする
    • ポリシをリソースドリブンで作成する
    • AWSマネジメントポリシをなるべく使わない
      • リソースが*なのでザルすぎる

IAM設計上の戦略と戦術については、波田野さんの資料が紹介されていました。

www.opslab.jp

感想

今回はハンズオン前の解説がいつも以上に長いことから、AWSの中で一番重要なサービスであることを改めて思い知らされました。下手な設定をして泣きを見ないよういつも以上に真剣に取り組まねばと思いました。また、今回の復習ブログだけでなく、定期的に復習して忘れないようにしないと!と思いました。

ハンズオンで出てきたコマンドについて何となくやっていることは分かったと以前も書きましたが、 認証ファイルの作成部分は少し複雑なコマンドで、何をやっているのか理解するのに時間がかかりました。 LinuxのコマンドやJMESPathの記述について、まだまだコマンドやスクリプトの一つひとつの意味を深堀りできてないと思いました。 時間を作ってLinuxコマンドとJMESPathに特化した勉強もしたいと思いました。自分でもスクリプトを書けるようになりたい…

ハンズオンで学んだコマンド

事前作業・ハンズオン手順は、こちらを参照してください。

なお、ハンズオン概要としては、以下の通りです。構成図は、こちらを参照してください。

  • IAMグループの作成とポリシのアタッチ
  • IAMユーザの作成とグループへの追加
  • APIアクセスキーの作成
  • APIアクセスキーの更新
  • ログインプロファイルの作成・削除
1.IAMグループの作成
  • グループ名を指定してiam create-groupでIAMグループを作成します。
aws iam create-group \
  --group-name ${IAM_GROUP_NAME}
  • 作成したグループを、iam list-groupsで存在確認します。
aws iam list-groups \
  --query "Groups[?GroupName == \`${IAM_GROUP_NAME}\`].GroupName" \
  --output text
2.IAMグループのポリシーアタッチ
  • グループ名とIAMポリシのARNを指定し、ima attach-group-policyを実行してポリシをアタッチします。
aws iam attach-group-policy \
  --group-name ${IAM_GROUP_NAME} \
  --policy-arn ${IAM_POLICY_ARN}

※IAMポリシのARNはiam list-policiesで取得します。

IAM_POLICY_ARN=$( \
  aws iam list-policies \
    --scope AWS \
    --max-items 1000 \
    --query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \
    --output text \
) \
  && echo "${IAM_POLICY_ARN}"
  • 指定したグループに指定したIAMポリシがアタッチされていることを、iam list-attached-group-policiesで確認します。
aws iam list-attached-group-policies \
  --group-name ${IAM_GROUP_NAME} \
  --query "AttachedPolicies[?PolicyName == \`${IAM_POLICY_NAME}\`].PolicyName" \
  --output text
3.IAMユーザの作成
  • ユーザ名を指定し、iam create-userでIAMユーザを作成します。
aws iam create-user \
  --user-name ${IAM_USER_NAME}
  • 作成したIAMユーザが存在することをiam list-usersで確認します。
aws iam list-users \
  --query "Users[?UserName == \`${IAM_USER_NAME}\`].UserName" \
  --output text
4.IAMユーザのIAMグループへの追加
  • IAMユーザをどのIAMグループに追加したいか指定して、iam add-user-to-groupでグループ追加します。
aws iam add-user-to-group \
  --group-name ${IAM_GROUP_NAME} \
  --user-name ${IAM_USER_NAME}
  • 指定のIAMユーザがIAMグループに追加されているか、iam list-groups-for-userで確認します。
aws iam list-groups-for-user \
  --user-name ${IAM_USER_NAME} \
  --query "Groups[?GroupName==\`${IAM_GROUP_NAME}\`].GroupName" \
  --output text
5.APIアクセスキーの作成
  • 現在のアクセスキーの数を確認します。
COUNT_IAM_ACCESS_KEYS=$( \
  aws iam list-access-keys \
    --user-name ${IAM_USER_NAME} \
    --query 'length(AccessKeyMetadata[])' \
) \
  && echo ${COUNT_IAM_ACCESS_KEYS}
  • 変数FILE_ACCESS_KEYにアクセスキーを保存するファイルパスを格納します。
    • ${DIR_ACCESS_KEY} にファイルディレクトリを指定します。
    • ${IAM_USER_NAME}にIAMユーザ名を指定します。
FILE_ACCESS_KEY="${DIR_ACCESS_KEY}/${IAM_USER_NAME}-token-${COUNT_IAM_ACCESS_KEYS}.json" \
  && echo ${FILE_ACCESS_KEY}
  • アクセスキーを作成するユーザを指定して、iam create-access-keyを実行します。
    • 同時にアクセスキーを先に指定したファイルパス(FILE_ACCESS_KEY)に保存します。
aws iam create-access-key \
  --user-name ${IAM_USER_NAME} \
  > ${FILE_ACCESS_KEY} \
    && cat ${FILE_ACCESS_KEY}
  • IAMユーザにアクセスキーが作成されたことをiam list-acccess-keysで確認します。
aws iam list-access-keys \
  --user-name ${IAM_USER_NAME} \
  --query 'AccessKeyMetadata[].[join(``,[CreateDate,`,`,Status])]' \
  --output text
6.AWS認証ファイルの作成

ここでは、認証情報(~/.aws/creadentialsファイル)とデフォルトリージョンなど設定情報(~/.aws/config)を作成します。

  • ~/.aws/creadentialsファイルに追加するために、INIファイルを作成します。
    • ${IAM_USER_NAME}にIAMユーザ名を指定します。
    • ${FILE_USER_CREDENTIAL}にINIファイルのパスを指定します。
    • ${FILE_ACCESS_KEY}に5.で作成したjsonファイル(アクセスキーが格納されている)を指定します。
    • jsonファイルからアクセスキーとシークレットアクセスキーを抜き出し、INIファイルに追記します。
echo "[${IAM_USER_NAME}]" > ${FILE_USER_CREDENTIAL}

cat "${FILE_ACCESS_KEY}" \
  | jp.py 'AccessKey' \
  | sed '/[{}]/d' | sed 's/[\" ,]//g' | sed 's/:/=/' \
  | sed 's/AccessKeyId/aws_access_key_id/' \
  | sed 's/SecretAccessKey/aws_secret_access_key/' \
  | grep '^aws_' \
  >> ${FILE_USER_CREDENTIAL} \
    && cat ${FILE_USER_CREDENTIAL}
  • ~/.aws/configファイルに追加するために、config形式のファイルを作成します。
    • ${FILE_USER_CONFIG} にconfigファイルのパスを指定します。
    • ${REGION_AWS_CONFIG}にデフォルトリージョンを指定し、${FILE_USER_CONFIG}で指定したファイルに追記します。
echo "[profile ${IAM_USER_NAME}]" > ${FILE_USER_CONFIG} \
  && echo "region=${REGION_AWS_CONFIG}" >> ${FILE_USER_CONFIG} \
  && echo "" >> ${FILE_USER_CONFIG} \
  && cat ${FILE_USER_CONFIG}
  • INIファイルの内容を ~/.aws/credentials に追記します。
cat ${HOME}/environment/conf-handson-cli-iam/handson-cli-user.ini >> ~/.aws/credentials
  • configファイルの内容を ~/.aws/config に追記します。
cat ${HOME}/environment/conf-handson-cli-iam/handson-cli-user.config >> ~/.aws/config
7.IAMユーザーの動作確認
  • デフォルトリージョンとユーザを指定します
export AWS_DEFAULT_REGION='ap-northeast-1'
export AWS_DEFAULT_PROFILE='handson-cli-user'
  • cloud9 list-environmentsでCloud9上の環境情報を取得します。
aws cloud9 list-environments
8.APIアクセスキーの作成
  • 5.と同じ手順でAPIアクセスキーをもう一つ作成します。
9.最新ではないアクセスキーの無効化
  • アクセスキーの作成日付をiam list-access-keysで取得します。
ARRAY_DATE_ISO8601=$( \
  aws iam list-access-keys \
    --user-name ${IAM_USER_NAME} \
    --query 'AccessKeyMetadata[].CreateDate' \
    --output text \
) \
  && echo ${ARRAY_DATE_ISO8601}
  • unsetコマンドで変数ARRAY_DATETIME_UNIXを解除します。
unset ARRAY_DATETIME_UNIX
  • アクセスキーの作成日時をUNIX時間形式で取得します。
if [ $(uname) == 'Linux'  ]; then \
  for i in $(echo ${ARRAY_DATE_ISO8601} ); do \
    DATETIME_UNIX="$( date -d ${i} +%s )" \
    ARRAY_DATETIME_UNIX="${ARRAY_DATETIME_UNIX} ${DATETIME_UNIX}" \
  ;done \
else \
  for i in $(echo ${ARRAY_DATE_ISO8601} ); do \
    DATETIME_UNIX="$( date -u -jf %FT%TZ ${i} +%s )" \
    ARRAY_DATETIME_UNIX="${ARRAY_DATETIME_UNIX} ${DATETIME_UNIX}" \
  ;done \
fi

echo ${ARRAY_DATETIME_UNIX}
  • 作成日が古い方のUNIX時間形式を取得します。
DATETIME_UNIX=$( \
  echo ${ARRAY_DATETIME_UNIX} \
    | awk 'BEGIN{CONVFMT = "%.10d"; OFMT = "%.10d";};{
      num = int (split($0, arr_input, " "));
      current = 1;
      for (i = 1; i <= num; i++) {
        arr_output[current] = arr_input[1];
        for (j = 1; j <= num; j++) {
          if ( j <= num ) {
            if ( arr_input[j] != NULL && arr_output[current] > arr_input[j] ){
               arr_output[current] = int (arr_input[j]);
               del = j;
            }
          }
        }
        delete arr_input[del];
        current++;
      }
      print arr_output[1];
    }' \
) \
  && echo ${DATETIME_UNIX}
  • 取得したUNIX時間形式をISO8601形式に変換します。
if [ $(uname) == 'Linux'  ]; then \
    DATE_ISO8601=$( date -d @${DATETIME_UNIX} +%Y-%m-%dT%TZ ); \
else \
    DATE_ISO8601=$( date -u -r ${DATETIME_UNIX} +%FT%TZ ); \
fi

echo ${DATE_ISO8601}
  • 作成日が古いアクセスキーを取得します。
IAM_ACCESS_KEY_ID=$( \
  aws iam list-access-keys \
    --user-name ${IAM_USER_NAME} \
    --query "AccessKeyMetadata[?CreateDate == \`${DATE_ISO8601}\`].AccessKeyId" \
    --output text \
) \
  && echo ${IAM_ACCESS_KEY_ID}
  • ユーザ名とアクセスキーを指定し、iam update-access-keyで無効(inactive)にします。
aws iam update-access-key \
  --user-name ${IAM_USER_NAME} \
  --access-key-id ${IAM_ACCESS_KEY_ID} \
  --status Inactive
  • ユーザ名に紐づくアクセスキーの状態をiam list-access-keysで確認します。
aws iam list-access-keys \
  --user-name ${IAM_USER_NAME} \
  --query 'AccessKeyMetadata[].[join(``,[CreateDate,`,`,Status])]' \
  --output text
10.IAMログインプロファイルの作成
  • ユーザIDとパスワードを指定します。
IAM_USER_NAME='handson-cli-user'

※xxxxxxxxxにパスワードを指定します。

IAM_PASSWORD_NEW='xxxxxxxxx'
  • ユーザ名とパスワードを指定してima create-login-profileを実行します。
aws iam create-login-profile \
  --user-name ${IAM_USER_NAME} \
  --password "${IAM_PASSWORD_NEW}"
  • 指定したユーザ名にログインプロファイルがあるか、iam get-login-profileを実行して確認します。
aws iam get-login-profile \
  --user-name ${IAM_USER_NAME} \
  --query 'LoginProfile.UserName' \
  --output text
11.IAMログインプロファイルの削除
  • ログインプロファイルを削除するユーザ名を指定して、iam delete-login-profileを実行します。
aws iam delete-login-profile \
  --user-name ${IAM_USER_NAME}
12.後始末

ハンズオン環境が不要になったら、ハンズオン手順の後始末以降の手順を実施します。

後始末で実行したコマンドは以下の通りです。

APIアクセスキーの全削除
  • 登録されているアクセスキーをすべて取得します。
ARRAY_IAM_ACCESS_KEY_IDS=$( \
  aws iam list-access-keys \
    --user-name ${IAM_USER_NAME} \
    --query 'AccessKeyMetadata[].AccessKeyId' \
    --output text \
) \
  && echo ${ARRAY_IAM_ACCESS_KEY_IDS}
  • ユーザ名とアクセスキーを指定してiam delete-access-keyで削除します。
    • すべて削除する場合は、for文でアクセスキーの数の回数実行します。
for i in ${ARRAY_IAM_ACCESS_KEY_IDS}; do
  aws iam delete-access-key \
    --user-name ${IAM_USER_NAME} \
    --access-key-id ${i}
done
  • ユーザ名に紐づくアクセスキーがないことをiam list-access-keysで確認します。
aws iam list-access-keys \
  --user-name ${IAM_USER_NAME} \
  --query "AccessKeyMetadata[].UserName" \
  --output text
AWS認証ファイルの削除
  • viなどエディタで .aws/credentials を開き、今回作成したIAMユーザに関する行のみを削除します。
[handson-cli-user]
aws_access_key_id=
aws_secret_access_key=
  • 同様にviなどで .aws/config を開き、今回作成したIAMユーザに関する行のみを削除します。
[profile handson-cli-user]
region=ap-northeast-1
IAMユーザのIAMグループからの削除
  • グループから削除させるユーザを指定してiam remove-user-from-groupを実行します。
aws iam remove-user-from-group \
  --group-name ${IAM_GROUP_NAME} \
  --user-name ${IAM_USER_NAME}
IAMユーザーの削除
  • 削除するIAMユーザを指定してiam delete-userを実行します。
aws iam delete-user \
  --user-name ${IAM_USER_NAME}
IAMグループのポリシーデタッチ
  • デタッチするIAMロールのARNとIAMグループを指定して、iam detach-group-policyを実行します。
aws iam detach-group-policy \
  --group-name ${IAM_GROUP_NAME} \
  --policy-arn ${IAM_POLICY_ARN}
IAMグループの削除
  • 削除するIAMグループ名を指定してiam delete-groupを実行します。
aws iam delete-group \
  --group-name ${IAM_GROUP_NAME}
Cloud9用ロールからのポリシーのデタッチ
  • IAMロール"handson-cloud9-environment-role"からIAMポリシー"IAMFullAccess"をデタッチします。
    • IAMフルアクセスを残したままにしておくと、不正に権限設定されてしまう恐れがあります。 ※GUIからデタッチします。手順は割愛します。

最後に

次回(今日)はこの続きでIAMポリシに特化したところになります。 次回もしっかりついていき理解を深めたいです。

※次回のイベントページ

jawsug-cli.connpass.com