はじめに
前回の記事では、セルフサービスな MFA 環境を作るための IAM Policy の方法を学びました。今回は、AWS CLI から MFA を利用するときの方法を整理したいと思います。
まず、前提知識として整理すると、AWS のマネージメントコンソールで MFA を有効化する設定項目があります。
これを有効化すると、マネージメントコンソールにログインするときに、MFA 認証が求められます。
この機能を有効化しただけでは、この IAM User に紐づくアクセスキーをつかった AWS CLI の実行には何も影響しません。表現を変えると、アクセスキーを払い出したら、MFA 関係なくいろいろな API が実行できるわけですね。
これだと困るので、IAM Policy で MFA が無いときにアクセスを禁止するルールを設定すると、AWS CLI でも MFA が有効になります。すごいシンプルな例だと、以下のとおりです。MultiFactorAuthPresent
が false
のときには、全てのアクションを禁止にしています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllDenyWithoutMFA",
"Effect": "Deny",
"Action": [
"*"
],
"Resource": [
"*"
],
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": false
}
}
}
]
}
なお、前回の記事でこれと同等な IAM Policy を設定していたので、この記事を参考にすると、すでに AWS CLI でも MFA が有効になっています。ちょっと試してみましょう。
アクセスキーの生成
上記の IAM Policy を紐づけている User でアクセスキーを生成します。
AWS CLI の Profile を作成します。
> aws configure --profile mfa
AWS Access Key ID [None]: secret1
AWS Secret Access Key [None]: secret2
Default region name [None]: ap-northeast-1
Default output format [None]: json
きちんと設定されました
> aws sts get-caller-identity --profile mfa
{
"UserId": "AIDA5WQZQQ3JP5PXAB573",
"Account": "xxxxxxxx",
"Arn": "arn:aws:iam::xxxxxxx:user/mfauser01"
}
AWS CLI が利用できない
アクセスキーを設定しても、MFA を使っていないので AWS CLI の実行ができません。想定通りですね。
> aws ec2 describe-instances --profile mfa
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
> aws s3 ls --profile mfa
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
AWS CLI で MFA を入力する
AWS CLI で MFA を利用するときには、aws sts get-session-token
コマンドで一時的なアクセスキーを取得できます。このコマンドを実行するために、MFA Device の ARN が必要です。
マネージメントコンソール上で ARN を確認してコピーします。
aws sts get-session-token
コマンドを実行します。
- serial-number : コピーしてきた MFA Device の ARN を指定
- token-code : この MFA Device が生成する 6 桁の数字を指定
aws sts get-session-token \
--serial-number arn:aws:iam::xxxxxxxxx:mfa/test-mfa3 \
--token-code 627292 \
--profile mfa
入力した値が正しければ、12 時間だけ使える一時的なアクセスキーが発行されます。永続的なものではないので、万が一流出しても 12 時間後には使えないため、セキュリティレベルが向上するわけですね。
{
"Credentials": {
"AccessKeyId": "secret1",
"SecretAccessKey": "secret2",
"SessionToken": "secret3",
"Expiration": "2022-12-29T15:19:29+00:00"
}
}
一時的に取得したアクセスキーは、export で環境変数に入れたりすると実際に AWS CLI で使えます。bash ですが、次のように簡単に環境変数に入れられます。Bash Script など作ってもいいかもしれないですね。
OUTPUT=$(aws sts get-session-token \
--serial-number arn:aws:iam::xxxxxxxx:mfa/test-mfa3 \
--token-code 311758 \
--profile mfa)
export AWS_ACCESS_KEY_ID=$(echo $OUTPUT | jq -r .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $OUTPUT | jq -r .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $OUTPUT | jq -r .Credentials.SessionToken)
さきほどまではエラーだったコマンドが実行できました。
$ aws ec2 describe-instances
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-0adb5d1dc8c5aa555",
"InstanceId": "i-0b5a7eef21d818f5b",
"InstanceType": "t2.large",
省略
$ aws s3 ls
2021-06-24 01:51:35 testsugi001001
2021-05-03 02:04:08 vmimport-bucket-sugi01
2021-07-23 22:33:00 vpcflowlogs001
2021-06-24 01:56:50 webpushtest-sugi01
便利ツール
AWS CLI 上で、毎回環境変数にセットするのは大変なので、次のツールや Shell Script が紹介されていました。このあたりを利用すると、とても便利になると思います。
Tips : 有効期限の指定
duration-seconds
をオプションで指定することで、一時的なクレデンシャルの有効期限を指定可能。最大値は 129600 (36 時間) となる。
aws sts get-session-token \
--serial-number arn:aws:iam::xxxxxxxx:mfa/test-mfa3 \
--token-code 812568 \
--duration-seconds 129600 \
--profile mfa
検証を通じてわかったこと
- AWS マネージメントコンソールで MFA を設定にしただけでは、AWS CLI 側には何も影響しない。MFA なくてもコマンド実行ができる
- 上記を防ぐために、IAM Policy で
MultiFactorAuthPresent
を使ったルールを指定することで、AWS CLI を経由した API 実行でも MFA を強制できる - AWS CLI 上では、get-session-token コマンドで MFA のトークンを入力すると、一時的なクレデンシャル情報を取得可能
- 一時的なクレデンシャルは、デフォルトだと 12 時間で有効期限がきれる。
duration-seconds
を指定することで、最大 36 時間まで伸ばせる。
参考 URL
AWSコンソールとCLI利用時にMFA認証を必須にする
https://www.karakaram.com/requiring-mfa-authentication-when-using-aws-console-and-cli/
AWS: MFA で認証された IAM ユーザーが [My Security Credentials] (マイセキュリティ資格情報) ページで自分の認証情報を管理できるようにする
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html
AWS CLI で MFA 必須のアクセス制御を設定
https://blog.nijot.com/aws/aws-cli-mfa-force-setting/