
AWS IAMユーザーのアクセスキーをスクリプト一発でローテーションする
こんにちは。サービスグループの武田です。
「AWSのセキュリティチェックツールを使ってみたら、君のアクセスキーが古いっていうアラート *1が出たから更新しといて」
「(よくわかってないけど)わかりました!」
さてAWSを使っているとこんな会話をすることもあるのではないでしょうか。アクセスキーとはAWS CLIなどからAWSを利用するためのクレデンシャル(認証情報)です。そしてこのアクセスキーは定期的にローテーション(更新)することが推奨されています。
IAM ユーザーのアクセスキーの管理 - AWS Identity and Access Management
また都元も次のようなエントリを以前にポストしています。当時のUIキャプチャで今とは多少異なりますが更新の手順は分かりますね。
ところで、セキュリティ上必要な作業だということは理解できますが、ぶっちゃけ面倒じゃないですか?手作業って。というわけで、面倒くさがりな自分のために簡単にキーローテーションできるスクリプトを書きましたのでシェアさせてください。
先にお断り
今回書いたスクリプトですが、自分のローカルPCのクレデンシャルしか更新しません。そのため複数の環境でアクセスキーを共有している場合、それらのプログラムが動かなくなります。そのようなケースでは使用しないでください。
スクリプトがエラーなどで途中で停止した場合、古いアクセスキーなどが残ったりします。そのようなケースでは手動でクリーンアップ処理を行ってください。またクレデンシャルファイル(credentials)はスクリプト内でコピーしています。必要であれば利用または削除などを行ってください。
環境
次のような環境で動作確認をしています。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.14.5 BuildVersion: 18F132 $ aws --version aws-cli/1.16.145 Python/3.7.0 Darwin/18.6.0 botocore/1.12.135 $ jq -V jq-1.5 $ echo $BASH_VERSION 4.4.23(1)-release
スクリプトの紹介
スクリプトはgistに上げてあります。好きに使ってください。
#!/bin/bash -euo pipefail | |
# | |
# Usage: | |
# $ aws-iam-user-key-rotation.sh [profile] [credential_file] | |
# | |
declare -x AWS_DEFAULT_PROFILE=${1:-default} | |
declare credential_file=${2:-~/.aws/credentials} | |
declare -x AWS_SHARED_CREDENTIALS_FILE=$credential_file | |
echo "${AWS_DEFAULT_PROFILE} プロファイルのアクセスキーをローテーションします。" | |
declare iam_user_name | |
iam_user_name=$(aws iam get-user | jq -r '.User.UserName') | |
declare current_access_keys | |
current_access_keys=$(aws iam list-access-keys) | |
echo "対象のIAMユーザーは ${iam_user_name} です。" | |
# AWSのアクセスキーは一度に2個までしか作成できないため先にチェックしておく | |
if (( $(echo "$current_access_keys" | jq '.AccessKeyMetadata | length') == 2 )); then | |
echo "アクセスキーが2個存在しています。使用していないアクセスキーを削除してから再実行してください。" 1>&2 | |
exit 1 | |
fi | |
cp "$credential_file"{,.bak} | |
declare new_credentials | |
new_credentials=$(aws iam create-access-key --user-name "$iam_user_name") | |
echo "新規アクセスキーを作成しました。" | |
declare response_text="$(echo "$new_credentials" | jq -r '.AccessKey.AccessKeyId') | |
$(echo "$new_credentials" | jq -r '.AccessKey.SecretAccessKey') | |
" | |
echo "$response_text" | aws configure > /dev/null | |
echo "クレデンシャルファイルを更新しました。" | |
declare updated_access_keys | |
echo "新しいアクセスキーで試行します。" | |
set +e | |
while :; do | |
echo "5秒待機します..." | |
sleep 5s | |
# このコマンドは新しいアクセスキーで実行される | |
updated_access_keys=$(aws iam list-access-keys 2> /dev/null) | |
(( $? == 0 )) && break | |
done | |
set -e | |
# ここがfalseになることはないはず | |
if (( $(echo "$updated_access_keys" | jq '.AccessKeyMetadata | length') != 2 )); then | |
echo "アクセスキーが2個存在していません。何かおかしいようです。" 1>&2 | |
exit 1 | |
fi | |
aws iam delete-access-key --user-name "$iam_user_name" --access-key-id "$(echo "$current_access_keys" | jq -r '.AccessKeyMetadata[0].AccessKeyId')" | |
echo "古いアクセスキーを削除しました。" |
基本的な使い方としてはダウンロード後、次にように第1引数にローテーションしたいプロファイルを指定するだけです。省略した場合はdefault
プロファイルを対象とします。
$ curl https://gist.githubusercontent.com/TAKEDA-Takashi/f06df456847a29fbdd752e19ab8389cb/raw/aws-iam-user-key-rotation.sh -o aws-iam-user-key-rotation.sh $ chmod +x aws-iam-user-key-rotation.sh $ ./aws-iam-user-key-rotation.sh classmethod
クレデンシャルファイルのパスを~/.aws/credentials
以外に設定している場合は、次のように、第2引数にそのパスを指定してください。
$ ./aws-iam-user-key-rotation.sh classmethod /tmp/cred
スクリプト内の処理は大まかに次の順番で行っています。詳細は中身を見てください。
- 使用中のアクセスキーIDを取得
- クレデンシャルファイルコピー(バックアップ)
- 新規アクセスキーを作成
- クレデンシャルファイルに新しいアクセスキーを設定
- 新しいアクセスキーでAPIアクセス
- 古いアクセスキーを削除
最後に
管理するアクセスキーは少ないほど好ましいです。更新するアクセスキーが多いなという方はIAMロールに変更できないかなど検討してみてください。また前述したようにキーローテーションは定期的に実行することが推奨されています。今回紹介したスクリプトをたとえば60日ごとに自動実行されるように設定することで、意識しなくてもセキュリティを向上できます。ぜひこのあたりのことも検討してみてください。