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を知ることは、AWSのAPIアクションとの付き合い方を知ること
- 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}
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ログインプロファイルの作成
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