AWS CLIのみでMFAを有効にする方法

記事タイトルとURLをコピーする

こんにちは。技術2課の芳賀です。皆さんAWS CLI(以降CLI)を使っているでしょうか。
私ですか?実はあまり多用はしていません・・・^^;

ところでCLIを使用する際にMFA認証させることができるのをご存知でしょうか。また、MFAの設定はマネコンからしかできないと思っていませんか?

最近、お客様環境で、CLIを用いて開発ベンダー様に作業してもらうためのIAMユーザを払い出す機会がありました。その際、開発ベンダー様にてMFAを有効化してもらう必要があったので手順についてまとめました。私の環境はWindowsなのでWindowsを例に説明しますが、Mac、Linuxでもコマンドに大きく差はありません。参考にして頂ければと思います。

1.CLI用のIAMユーザーを作成


今回はアクセスの種類「プログラムによるアクセス」のみ選択した「CLI-user」というIAMユーザを作成しました。
ポリシーは必要に応じて設定します。
(例としてS3の一覧取得を行うので、今回はS3へのフルアクセスポリシーなど付与しました)

CLIのインストール方法については割愛します。インストール方法は下記URLを参照ください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html

2.CLIにてS3バケット名の一覧を取得

まずMFAの設定を行う前にCLIでAWSにアクセスしてみましょう。
「aws configure」のコマンドで作成したIAMユーザのアクセスキー、シークレットアクセスキーなどを設定します。

「aws s3 ls」のコマンドでS3のバケット名の一覧を取得してみます。

問題なくS3のバケット名の一覧が取得できました。

3.IAMポリシーのアタッチ

CLI実行時、必ずMFA認証を求めるようにする為には、以下のIAMポリシーをIAMユーザーにアタッチする必要があります。

Conditions セクションの"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}の箇所がMFAを使用して認証されたか判断する書き方になります。


ただ、このIAMポリシーでは「4.CLIで仮想MFAデバイスのエンティティ作成」以降のMFA設定もMFA認証してからでなくては操作できない為、自身のMFA設定などの操作のみ許可するよう以下のポリシーをアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": [
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary",       
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },       
        {
            "Sid": "AllowManageOwnPasswords",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:GetUser"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSigningCertificates",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSigningCertificate",
                "iam:ListSigningCertificates",
                "iam:UpdateSigningCertificate",
                "iam:UploadSigningCertificate"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSSHPublicKeys",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSSHPublicKey",
                "iam:GetSSHPublicKey",
                "iam:ListSSHPublicKeys",
                "iam:UpdateSSHPublicKey",
                "iam:UploadSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnGitCredentials",
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceSpecificCredential",
                "iam:DeleteServiceSpecificCredential",
                "iam:ListServiceSpecificCredentials",
                "iam:ResetServiceSpecificCredential",
                "iam:UpdateServiceSpecificCredential"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:mfa/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

【参考URL】
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html

ポリシーをアタッチした後、「aws s3 ls」のコマンドを実行すると以下のようなアクセスが拒否された旨のエラーが返ってきます。

4.CLIで仮想MFAデバイスのエンティティ作成

ここからCLIにてMFAの設定を行っていきます。
CLIにて以下のコマンドを実行し、仮想MFAデバイスのエンティティを作成します。
(※見やすさのため、オプション設定毎に改行を入れています)

aws iam create-virtual-mfa-device 
 --virtual-mfa-device-name {MFAデバイス名} 
 --outfile {ファイルパス}/{画像名.png} 
 --bootstrap-method {QRCodePNG or Base32StringSeed}

今回は各オプションに以下を指定しました。

オプション名 設定値 説明
--virtual-mfa-device-name CLI-user 任意の仮想MFAデバイス名を指定します。
ただし、3.にてアタッチしたポリシーの内容から、IAMユーザーのユーザー名と一緒の名前を指定する必要があります。
--outfile C:/QRCode.png 仮想MFAデバイスで読み込むQRコードの画像を保存するパスを指定します。
(Linux、Macだと 「~/QRCode.png」など)
--bootstrap-method QRCodePNG QRコードの画像ファイルの形式を指定します。
QRCodePNG か Base32StringSeedが指定できます。

以下のような内容が返ってきます。

「SerialNumber」キーの値は、仮想MFAデバイスを登録する際に使用するのでメモしておきます。

【参考URL】
https://docs.aws.amazon.com/cli/latest/reference/iam/create-virtual-mfa-device.html

コマンドにて指定したパスにQRコードの画像が保存されます。
こちらも仮想MFAデバイスを登録する際に使用します。

別のIAMユーザーにてAWSマネージメントコンソール(以降マネコン)にログインし、「CLI-user」の認証情報を確認すると、現時点ではIAMユーザーの指定などしていない為、まだ仮想MFAデバイスの割り当てがされていないことがわかります。

5.仮想MFAデバイスの割り当て

ここではCLI用に作成したIAMユーザーに仮想MFAデバイスの割り当てをします。
今回は2段階認証アプリとして「Authy」を使用します。「Authy」は以下よりダウンロードできます。
https://authy.com/download/

先ほど保存したQRコードの画像をAuthyで読み取り、仮想MFAデバイスを登録します。

登録完了後、以下のコマンドを実行します。
(※見やすさのため、オプション設定毎に改行を入れています)

aws iam enable-mfa-device 
 --user-name {IAMユーザー名} 
 --serial-number {SerialNumberの値} 
 --authentication-code-1 {Authyのトークン(1回目)} 
 --authentication-code-2 {Authyのトークン(2回目)}

今回は各オプションに以下を指定しました。

オプション名 設定値 説明
--user-name CLI-user 仮想MFAデバイスを割り当てるIAMユーザー名を指定します。
--serial-number 説明を参照 「3.CLIで仮想MFAデバイスの設定」でメモした「SerialNumber」キーの値を指定します。
--authentication-code-1 説明を参照 Authyに表示された6桁のトークンを指定します。
次の「--authentication-code-2」オプションには、「--authentication-code-1」に指定した次の連続したトークンを指定します。  
--authentication-code-2 説明を参照

【参考URL】
https://docs.aws.amazon.com/cli/latest/reference/iam/enable-mfa-device.html

再度、別のIAMユーザーにてマネコンにログインし、「CLI-user」の認証情報を確認すると、IAMユーザに仮想MFAデバイスの割り当てられたことが確認できました。
(画面をリロードしても割り当てが確認できない場合は、一旦別なAWSサービスの画面に遷移したのち再度確認してみてください)

CLIでこんな面倒なことをやらずに、マネコンから仮想MFAデバイスを登録すれば良いのでは?と思われるかもしれません。
確かにマネコンにログインでき認証情報を設定できるIAMユーザーがいれば可能かと思いますが、今回はアクセスの種類「プログラムによるアクセス」のみ選択したIAMユーザーで、かつお客様や開発ベンダー様に仮想MFAデバイスの設定をしてもらうことを想定しています。デバイス自体もお客様、開発ベンダー様に用意してもらう必要があるため今回のケースではCLIで行う必要があります。
(デバイスを送ってもらう、QRコードを何らかの方法で共有してAuthyのトークンコードを教えてもらうなども可能とは思いますが…)

6.CLIでのMFA認証方法

CLIでMFA認証するためには以下「sts get-session-token」コマンドを実行します。
(※見やすさのため、オプション設定毎に改行を入れています)

aws sts get-session-token 
 --serial-number {MFAデバイスのARN} 
 --token-code {Authyのトークン}
オプション名 説明
--serial-number MFAデバイスのARNを指定します。マネコンのIAMユーザーの認証情報タブにて確認できます。
--token-code Authyに表示された6桁のトークンを指定します。

「--duration-seconds」オプションを使用することで、MFAの有効期限を指定できるようです。デフォルトは12時間。

以下のような形式で、アクセスキー、シークレットアクセスキー、セッショントークンなどの結果が返ってきます。

以下のコマンドを使用して値を環境変数に設定することで、一時的に認証を許可します。

set AWS_ACCESS_KEY_ID={アクセスキー}
set AWS_SECRET_ACCESS_KEY={シークレットアクセスキー}
set AWS_SESSION_TOKEN={セッショントークン}

【参考URL】
https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/

環境変数に設定した後、「aws s3 ls」のコマンドを実行すると、エラーにならず結果が返ってくるようになりました。

まとめ

以上、CLIのみでMFAを有効にする方法でした。いかがだったでしょうか?
作業に必要なポリシーと、「3.」のポリシーをアタッチしてもらったIAMユーザーのクレデンシャル情報さえもらえれば、こちらでMFAの設定をすることができ、安全に作業することができるようになりますね。

CLIを多用しない私にとっては少し複雑な手順に感じましたが、これを機にもう少しCLIを使っていきたいと思います!!
参考になりましたら幸いです。