🔑

AWS CLIでMFA認証するならアカウント内スイッチロール

2024/04/01に公開

セキュリティのために、IAMユーザーのMFAを設定している方も多いことと思います。

ちなみに、以下のようなIAMポリシー[1][2]を使えば、ユーザーにMFAログインを強制することができますね。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:GetMFADevice",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken",
                "iam:ChangePassword",
                "iam:GetAccountPasswordPolicy"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

マネジメントコンソールでは、一度MFAを設定すればログイン時にMFAコードの入力を求められるため、MFAログインに苦労することはありません。しかし、AWS CLIでのMFAログインには意外と苦労します

最も順当な方法は、aws sts get-session-tokenコマンドを実行して得られた結果(認証情報)を、AWS CLIが参照する環境変数等に設定することです[3]。手作業で普段からこれを実行するのは流石につらいので、少なくともシェルスクリプト化は必須だと思います。しかし、シェルスクリプト化したとしても、認証情報の有効期限が切れるたびに毎回自発的に認証情報の再設定を行う必要があることは、少し面倒です。

普通にAWS CLIを実行して、必要だったらその時自動的にMFAコードの入力を求めてくれたらいいのになあ……」と思いませんか? 私は思いました。それを実現する方法を紹介します。

アカウント内でスイッチロールしてコマンド実行されるようにAWS CLIを構成する

スイッチ先のIAMロールを作成する

まずは、スイッチ先のIAMロールを作成します。スイッチ元のIAMユーザーからスイッチ可能なIAMロールを作成してください。

信頼ポリシーの例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "123456789012"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

ここで作成したIAMロールARNは、後で使用します。

AWS CLIのプロファイルを設定する

前提として、スイッチ元ユーザーのアクセスキーが~/.aws/credentialsに登録済みであることとします。プロファイル名は、何でもよいですが、以下の例ではsource-profileとしています。

~/.aws/credentials
[source-profile]
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXX

そして、~/.aws/configにスイッチ後のプロファイルを登録します。以下の例では、プロファイル名をmfa-profileとしていますが、ここをdefaultとしておくのもおすすめです(※そのためには、スイッチ元プロファイル名をdefault以外にしておく必要があります[4])。プロファイルには、role_arnにスイッチ先ロールのARNを、source_profileにスイッチ元プロファイル名を、mfa_serialにスイッチ元ユーザーのMFAデバイスARNを指定します。

~/.aws/config
[profile mfa-profile] 
role_arn = arn:aws:iam::123456789012:role/cli-role
source_profile = source-profile
mfa_serial = arn:aws:iam::123456789012:mfa/cli-user

以上で事前準備は完了です。

使い方

スイッチ先プロファイルでAWS CLIを実行してください。そうすると、必要な場合に限り、MFAコードの入力が求められます。入力すると、コマンドの実行結果が得られます。

$ aws sts get-caller-identity --profile mfa-profile
Enter MFA code for arn:aws:iam::123456789012:mfa/cli-user:
{
...
}

ここで、スイッチ後のプロファイル名をdefaultにしておけば--profileオプションが省略できて更に楽になります。

複数のユーザーがいる場合

アカウントに複数のIAMユーザーがいる場合は、IAMロールを共用することもできますが、個別のIAMロールを用意することもご検討ください。例えば、CloudTrailログではsts:AssumeRoleイベント以外にはスイッチ元のユーザー名が記録されないため、個別のIAMロールを使用したほうがこうした情報を追跡しやすくなります。

その他の方法

インストールのハードルがありますが、非公式のMFAログイン補助ツールを使う方法もあります。興味があれば調べてみてください。

脚注
  1. IAM チュートリアル: ユーザーに自分の認証情報および MFA 設定を許可する - AWS Identity and Access Management ↩︎

  2. 【IAM】MFA 強制ポリシーの注意点【多要素認証】 - サーバーワークスエンジニアブログ ↩︎

  3. AWS CLI 経由で MFA を使用してアクセスを認証する | AWS re:Post ↩︎

  4. 試していないですが、多分…… ここでプロファイル名が衝突するとどうなるんでしょうね ↩︎

Discussion