2019.07.16
STAFF BLOG
スタッフブログ
TECHNICAL
テクログ
![](https://core-tech.jp/wp-content/themes/cor_corp_theme02/img/blog/thumb/tech_log.png)
??????! ?? ????(????) ????
ナマステー!
こんにちは。インフラ担当のまつやです。
弊社ではWebサービスの基盤としてAWS(Amazon Web Service)を主に使っています。
エンジニアはAWSコンソールからログインして作業することが多いため、メンバーが
増えるたびにアカウントを発行する必要があります。
このアカウント作成はAWSコンソールにログインし、
IAM(Identity and Access Management)から作成できますが、発行頻度が増えてくる
とGUIからのアカウントの発行・通知がやや大変になってきました。
そこで、AWS CLI(コマンドラインインターフェイス)を利用して、ユーザー発行に必要
なコマンド操作を一括で行えるシェルスクリプトを作成することにしました。
また弊社ではAWSコンソールからのログインにパスワード設定の上、MFAデバイス
による二段階認証を必須としています。この二段階認証も同時に設定してしまい、
パスワード情報と二段階認証用のQRコードをユーザーに通知するだけで済むように
したいと思います。
Amazon Linuxのbash環境で作成しています。
python(2.7)
aws-cli(最新版)
oathtool
が必要になります。
以下が本体のシェルスクリプトです。
#!/bin/bash
set -e
# 環境変数設定
export BASE_DIR=${HOME}/iam
#
# usage
#
usage_exit() {
echo "usage:"
echo "${0} -u USERNAME [-g GROUP] [-a] [-h]" 1>&2
echo "-a: create API key for each user." 1>&2
echo "-h: this help." 1>&2
exit 1
}
#パスワード生成コマンド
password_command="cat /dev/urandom | tr -dc "12345678abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ+-!" | fold -w 16 | grep -E "[123456789]" | grep -E "[+-!]" | grep -E "^[123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ]" |head -n 1"
#引数の設定
while getopts "u:g:h" OPT
do
case $OPT in
"u") CREATE_USER="true"; username=${OPTARG}
;;
"g") ADD_TO_GROUP="true"; group=${OPTARG}
;;
"h") usage_exit
;;
?) usage_exit
;;
esac
done
# 引数でユーザーを指定しない場合終了する。
[ "${CREATE_USER}" != "true" ] && usage_exit
#IAMユーザーのクレデンシャル情報格納用のディレクトリを作成。
if [ "${CREATE_USER}" = "true" ]; then
if [ ! -e "${BASE_DIR}/account/${username}" ]; then
mkdir -p ${BASE_DIR}/account/${username}
else
echo "Directory ${username} already exists."
fi
#IAMユーザー作成
aws iam create-user --user-name ${username} --profile default
aws iam wait user-exists --user-name ${username}
#二段階認証の仮想MFAデバイスを作成
aws iam create-virtual-mfa-device --virtual-mfa-device-name ${username}
--bootstrap-method Base32StringSeed
--outfile ${BASE_DIR}/account/${username}/${username}_secret.txt
#クレデンシャル情報ファイルに出力する内容
secret_key=`cat ${BASE_DIR}/account/${username}/${username}_secret.txt`
signin_url="https://AWSアカウント名.signin.aws.amazon.com/console"
password=$(eval ${password_command})
#ログインパスワードの設定&初回ログイン時のパスワード強制変更をオンにする
aws iam create-login-profile --user-name $username
--password ${password} --password-reset-required --profile default
#クレデンシャル情報をファイルに出力
echo "User name,Password,Secret access key,Console login link
${username},${password},${secret_key},${signin_url}" > ${BASE_DIR}/account/${username}/${username}_password.csv
#二段階認証用のQRコードを生成
python /home/ec2-user/iam/qrcodegen.py "otpauth://totp/Amazon%20Web%20Services:${username}@AWSアカウント名?secret=${secret_key}&issuer=Amazon%20Web%20Services" ${BASE_DIR}/account/${username}/${username}_qr.png
# Login Profile が完全にできているか確認してから次へ進む
aws iam wait user-exists --user-name ${username}
#ワンタイムパスワードを発行する
code="oathtool --totp -d 6 --time-step-size=30s --base32 ${secret_key}"
code1=$(eval ${code})
while :
do
code2=$(eval ${code})
if [ $code2 != $code1 ]; then
break;
fi
done
#二段階認証をオンにする
aws iam enable-mfa-device --user-name ${username}
--serial-number arn:aws:iam::XXXXXXXXXXXX:mfa/${username}
--authentication-code1 ${code1} --authentication-code2 ${code2}
#(注: arn:aws:iam::XXXXXXXXXXXX:mfa の12桁のXXXXXXXXXXXXにはAWSアカウントIDが入ります)
else
usage_exit
fi
# 引数で-gを指定した場合 ユーザー ${username} にグループ ${group} を割り当てる
if [ "${ADD_TO_GROUP}" = "true" ]; then
aws iam wait user-exists --user-name ${username}
aws iam add-user-to-group --group-name ${group}
--user-name ${username}
--profile default
fi
-u username の形式でユーザー名の指定を必須にしています。ここで指定したユーザー名
を使って処理が進みます。
まず、基本のIAMユーザー作成を行います。aws iam wait user-existsでユーザーが作成された
ことを確認して先に進みます。
次に二段階認証用の仮想MFAデバイスを作成します。AWSコンソールから作成する場合はIAM
ユーザーと同じ名前で作成されますが、CLIで作成する場合はデバイス名が重複しない限りは
IAMユーザー名と異なっていても別の名前のデバイスを作成し、関連付けをすることができます。
ここでは管理が面倒になるので、IAMユーザ名と一致させます。
MFAデバイス作成と同時にシークレットキーを発行します。ここではQRコードの形でも発行で
きますが、シークレットキーと同時に発行することができないため、シークレットキーを発行し、
そのシークレットキーを元に別途QRコードを作成します。
次にログインパスワードを設定します。初回ログイン時に強制的にパスワード変更させるオプシ
ョンを有効にします。
この時発行するパスワードですが、cat /dev/urandomして tr -dcとかで切り出して、16文字のも
のを生成しています。小文字のエル、数字の0と大文字小文字のオーは除外しています。
パスワードコマンドはこれに限らずpwgenとかが使えるならそれでいいかと思います。
次にQRコードの生成です。pythonのqrcodeライブラリを使います。pipでインストールします。
pip install qrcode
インストールしたら、中間プログラムを作成します。ここではqrcodegen.pyとしています。
qrcodegen.py
import qrcode
import sys
import os
args = sys.argv
qr = qrcode.QRCode(
version=4,
error_correction=qrcode.constants.ERROR_CORRECT_M,
box_size=6,
border=4,
)
qr.data = args[1]
qr.save_path = args[2]
qr.add_data(qr.data, 20)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save(qr.save_path)
これを使ってQRコードを生成します。
MFAデバイスを作成したときの ${username}_secret.txt を${secret_key}に指定します。
${username}@AWSアカウントの箇所はご自身の環境に合わせて読み替えて下さい。
これでIAMユーザー毎のクレデンシャル情報格納ディレクトリにQRコードが生成されま
す。
二段階認証を有効にします。
oathtoolを使用してワンタイムパスワードを発行します。これを都合2回入力することで
二段階認証が有効になります。Amazon Linuxでは基本のリポジトリには存在しないので、
epelリポジトリからインストールします。epelリポジトリを有効にする方法はここでは割
愛します。
発行したシークレットキーを元に6桁のワンタイムパスワードを発行します。whileでこの
パスワード発行コマンドを実行し、初めにに発行した値と異なる値になるまで回します。
ここでcode1とcode2を取得します。code1とcode2を使って二段階認証をオンにします。
最後に-gでグループを引数に指定した場合の処理です。指定したグループをユーザーに割
当てます。指定しなければスルーします。
以上のようにして、事前に二段階認証をオンにした状態でIAMユーザー情報を各エンジニ
アに展開しています。エンジニアは発行されたパスワードとQRコード、あるいはシーク
レットキーを元にAWSコンソールにログインできます。
この他に、二段階認証がオフになっているユーザーがいないかを監視するLambdaのスクリ
プトも作成していますが、それについてはまたの機会に。
・参考にした記事
https://dev.classmethod.jp/etc/aws-cli-iamuser-bulk-create/
https://dev.classmethod.jp/cloud/aws/virtual-mfa-by-aws-cli/
それではまた!
??? ???????!