AWS CLI で MFA 必須のアクセス制御を設定

AWS CLI を利用する場合は、通常はアクセスキーの設定が必要となります。(EC2 上でIAM ロールを割り当てる場合は除く)
IAM ユーザ名/パスワードと違いアクセスキーはファイルなどに保存しておきますので漏洩のリスクが高くなります。そこでMFA 認証をしないとAWS CLI から各種AWS リソースにアクセスできないように設定する方法を記載します。

MFA 必須のIAM ポリシーの設定

まずは、以下のようなIAM ポリシーを設定します。MFA 認証をしていないとすべてのリクエストを拒否する設定となっています。
condition 内の記述ですが、”aws:MultiFactorAuthPresent” がMFA 認証されているかどうかを表していますが、MFA 認証をしていないとそもそもキーが存在しないため、”BoolIfExists” で存在チェックを入れています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllDenyWithoutMFA",
            "Effect": "Deny",
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": false
                }
            }
        }
    ]
}

アクセスキーを払い出すIAM ユーザにこのポリシーを付与しておけば、他のポリシーが設定されていたとしても、MFA が有効ではないリクエストはすべて拒否されるようになります。このため仮にアクセスキーが漏れてしまったとしても不正アクセスはされません。

なお、このポリシーはマネジメントコンソールのログインでもMFA 認証していないとリソースへのアクセスが許可されないようになりますので、管理者用IAM グループなどに設定しておくと、うっかりMFA 設定していないユーザを作ってしまったとしてもアクセスできませんので非常に安全です。

IAM ユーザへMFA を設定

IAM ユーザはログイン時のMFA を予め登録しておきます。設定の仕方は、以下のハンズオンを参照してください。こちらは、ルートユーザの設定方法ですが、IAM ユーザへのMFA の設定もほぼ一緒です。

https://github.com/tomofuminijo/aws-handson-labs/blob/master/RootUserMFA/howtoconfiguremfa.md

MFA 必須の IAM ロールの作成

今回のCLI の構成は、CLI 経由でassumeRole を実施しその際にMFAを利用するという構成を取ります。このため、MFA 必須のIAM ロールを作成します。

IAM ロールを作成するときは、”別のAWS アカウント” の種類を選択肢、”MFA が必要” にチェックを入れて作成します。アカウントID の部分は、ご自身のアカウントID を入力すればよいです。

アクセス権限は必要なものを設定しましょう。

AWS CLI の設定

AWS CLI の config ファイルに以下のような内容を記載します。カッコ(<>) で囲まれた部分はご自身の環境に置き換えてください。

[profile <any-name-1>]
aws_access_key_id = <your-access-key-id>
aws_secret_access_key = <your-secret-access-key>

[profile <any-name-2>]
region = <your-favorit-region>
# 上の手順で作成したIAM ロールのARNE を指定
role_arn = arn:aws:iam::<Your-Account-ID>:role/<iam-role-name>
# IAM ユーザのMFA デバイスのARN を指定
mfa_serial = arn:aws:iam::<Your-Account-ID>:mfa/<iam-user-name>
source_profile = <any-name-1>

MFA デバイスのARN はIAM ユーザの “認証情報” で確認できます。

AWS CLI の実行

AWS CLI 実行時に以下のように –profile で上記の <any-name-2> を指定して実行します。

aws ec2 describe-instances --profile <any-name-2>

そうすると、次のようにMFA コードの入力を促すプロンプトが表示されますので、ターミナル上でMFA コードを入力してEnter を押します。MFA 認証が正常に通ればコマンドが実行されて結果が表示されるはずです。

Enter MFA code for arn:aws:iam::<your-account-id>:mfa/<iam-user-name>:

なお、コマンド実行後は、assumeRole の結果(一時的認証情報) がキャッシュされており、2回目以降のコマンドではMFA コードは入力しなくても実行できます。(セッションが切れるまで)
キャッシュは、” ~/.aws/cli/cache” ディレクトリの中に保存されています。

(別の方法) GetSessionToken の利用

AWS CLI でMFA を利用する別の方法としては、AWS STS のGetSessionToken API を利用するという方法があります。具体的な手順は以下のURLを参照してください。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/

IAM ロールを利用する方法と比べると、自分自身のIAM ユーザに対するMFA 認証済みの一時的認証情報を取得できますので、IAM ロールがなくてもMFA をAWS CLI で利用することができます。

また、その他の細かい内容としては、AssumeRole でMFA トークンを指定しても、その一時的認証情報にはMFA 情報が含まれていません。

AssumeRole によって返される一時的な認証情報のコンテキストには MFA 情報が含まれていない

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html

例えば、Organizations のSCP などで、MFA 認証されていないリクエストはすべてDeny するといった運用をしている場合は、GetSessionToken を利用する必要があります。

追記

この記事の内容ですと、MFA の設定は管理者が行って上げる必要がありました。個人で利用している分には問題ありませんが、複数人で運用する場合は、MFA 設定は個人でセルフサービスで実施できることが望ましいです。
以下の記事で、セルフサービスでMFA を設定できるIAM ポリシーの記述方法を記載しましたのでこちらをご参照ください。

追記2

さらに、大規模なアカウント運用をすると認証情報を単一のアカウントで一元管理し、そのアカウントに一旦サインインした後に、別のアカウントにAssumeRole でアクセスするといった運用方式が考えられます。そのような大規模アカウント管理でもすべてのアクセスにMFA を必須とするほうがより安全に運用できます。この内容に関して、以下に記載していますのでご参照ください。

以上です。