MFAが有効化されていないIAMユーザーのMFA有効化の手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、MFAが有効化されていないIAMユーザーに対してMFAを有効化させる手順について解説します。

画像に alt 属性が指定されていません。ファイル名: 13e11608c3ab504725ce4500088eb55e-1024x341.webp

ポリシーの説明

[IAM.5] コンソールパスワードを使用するすべての IAM ユーザーに対して MFA を有効にする必要があります

IAM の Security Hub コントロール – AWS Security Hub

IAMユーザーのセキュリティを強化し、不正アクセスのリスクを大幅に低減するために、AWS管理コンソールにアクセス可能なすべてのIAMユーザーに対して多要素認証(MFA)の有効化を必須とすべきです。この対策は以下の理由で極めて重要です:

  1. 防御層の追加: パスワード認証が突破されても、MFAが有効な場合、攻撃者はアカウントへのアクセスを得ることができません。これにより、単一障害点を排除し、セキュリティの深層防御を実現します。
  2. フィッシング攻撃への対策: MFAは、フィッシング攻撃によってパスワードが漏洩した場合でも、アカウントを保護する効果的な手段となります。
  3. コンプライアンス要件の充足: 多くの業界標準(PCI DSS、HIPAA、GDPRなど)で、重要なシステムへのアクセスにMFAが要求されています。
  4. アクセス管理の強化: MFAの導入により、正規ユーザーの本人確認がより確実になり、不正アクセスのリスクを最小限に抑えることができます。

実装上の注意点:

  • 物理的なデバイス(ハードウェアトークン)、仮想MFAデバイス(スマートフォンアプリ)、U2Fセキュリティキーなど、複数のMFAオプションを提供し、ユーザーの利便性を考慮してください。
  • MFA設定のプロセスを文書化し、新規ユーザー作成時の標準手順に組み込んでください。
  • 定期的にMFA非準拠ユーザーを監査し、適切な措置を講じてください。

修復方法

MFAが有効化されていないコンソールアクセス可能なIAMユーザーに対する修正方法として、以下のパターンが考えられます。

  1. 強制的にMFA有効化させるIAMポリシーを割り当てる
    • IAMポリシーを作成し、MFAが設定されていないユーザーのアクセスを制限します。
    • これにより、ユーザーは自身でMFAを設定するまでコンソールの機能を利用できなくなります。
  2. AWS Organizationsを使用してSCPでMFA設定の強制化を適用する
    • 新規IAMユーザー作成時にMFA設定を必須とするワークフローを実装します。
    • AWS Organizationsを使用して、組織全体でMFA設定を強制するSCPを適用します。
  3. 手動でのMFA有効化:
    • 各ユーザーに連絡し、MFAの設定を促します。
    • AWSコンソールでIAMユーザーごとにMFAデバイスを追加します。

3はさておき、そもそもMFA設定がされていない状態で操作できる事自体が問題だと思いますので、それ自体を無くしましょうというところですね。

1と2についてそれぞれ試してみたいと思います。

1.修復方法: 強制的にMFA有効化させるIAMポリシーを割り当てる

AWSコンソールでの修正手順

  1. IAMダッシュボードに移動し、左側のナビゲーションパネルで「ユーザー」を選択します。

2. 表示されたユーザーの中から調べたいユーザーをクリックしMFAデバイスの割り当てをクリックします。

3. MFAデバイスを選択します。今回はスマートフォンアプリ「Google Authenticator」を使用した場合のMFA追加方法についてご説明します。 デバイス名を入力し、「認証アプリケーション」を選択後、次へをクリックします。

  1. 各種アプリストアからGoogleAuthenticatorをダウンロードします(詳細はこちらのドキュメントをご確認ください。Get verification codes with Google Authenticator – Android – Google Account Help) または、Windows PCであれば「WinAuth」を使用し多要素認証が行えますので、そちらも検討ください。https://winauth.github.io/winauth/download.html
  2. Google Authenticatorをセットアップした後、AWSコンソールの画面にて、QRコードを表示を押して、QRコードを表示します。 WinAuthをご利用の場合は、「シークレットキーを表示」をクリックしWinAuth画面でコードを入力します。
  1. Google Authenticator上で右下の+ボタンからQRコードリーダーを起動させ、5で表示したQRコードを読み取ります。
  2. その後、GoogleAuthenticator上で表示される6桁の数字をMFAコード1に入力します。
  3. GoogleAuthenticator上に表示される6桁の数字は数十秒間に一回更新されます。7で入力した後に更新された次の6桁の数字をMFAコード2に入力します。
  4. 保存をして完了です。

TerraformでIAMポリシーを作成

# MFA強制ポリシーの定義
resource "aws_iam_policy" "enforce_mfa" {
  name        = "EnforceMFAPolicy"
  path        = "/"
  description = "Policy to enforce MFA for IAM users"

  policy = jsonencode({
    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/*"
      },
      {
        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"
          }
        }
      }
    ]
  })
}

# 既存のIAMユーザーを取得
data "aws_iam_users" "all" {}

# MFAポリシーをすべてのIAMユーザーに適用
resource "aws_iam_user_policy_attachment" "enforce_mfa_for_all" {
  for_each = toset(data.aws_iam_users.all.names)
  user     = each.value
  policy_arn = aws_iam_policy.enforce_mfa.arn
}

AWS CLIでIAMポリシーを作成

#!/bin/bash

# MFA強制ポリシーのJSONファイルを作成
cat << EOF > enforce_mfa_policy.json
{
    "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/*"
        },
        {
            "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"
                }
            }
        }
    ]
}
EOF

# ポリシーを作成
aws iam create-policy --policy-name EnforceMFAPolicy --policy-document file://enforce_mfa_policy.json

# ポリシーのARNを取得
policy_arn=$(aws iam list-policies --query 'Policies[?PolicyName==`EnforceMFAPolicy`].Arn' --output text)

# すべてのIAMユーザーにポリシーを適用
for user in $(aws iam list-users --query 'Users[*].UserName' --output text); do
    echo "Attaching MFA enforcement policy to user: $user"
    aws iam attach-user-policy --user-name $user --policy-arn $policy_arn
done

echo "MFA enforcement policy has been created and attached to all IAM users."

# 一時ファイルの削除
rm enforce_mfa_policy.json

MFAが有効化されていないユーザーに対してはログイン後操作が出来ないことが確認できるかなと思います。

今後IAMユーザーを作成した際にはこのポリシーを付与すれば解決というところですね。

修復方法2: AWS Organizationsを使用してSCPでMFA設定の強制化を適用する

どちらかと言うとこちらが本筋ではないかなと思います。Organizationsを利用している環境であれば有効にしてもらいたい設定です。

ここではTerraformでの修正手順をまとめてみます。

Terraformでの修正手順

# IAMユーザー作成時にMFAを強制するポリシー
resource "aws_iam_policy" "enforce_mfa_on_creation" {
  name        = "EnforceMFAOnCreation"
  path        = "/"
  description = "Policy to enforce MFA setup during IAM user creation"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "EnforceMFAOnCreation"
        Effect = "Deny"
        Action = [
          "iam:CreateLoginProfile",
          "iam:CreateAccessKey"
        ]
        Resource = "*"
        Condition = {
          BoolIfExists = {
            "aws:MultiFactorAuthPresent" = "false"
          }
        }
      }
    ]
  })
}

# IAMユーザーを作成する権限を持つグループにポリシーをアタッチ
resource "aws_iam_group_policy_attachment" "user_creators_mfa_enforcement" {
  group      = "UserCreators"  # IAMユーザーを作成する権限を持つグループ名に変更してください
  policy_arn = aws_iam_policy.enforce_mfa_on_creation.arn
}

# AWS Organizations の設定
resource "aws_organizations_organization" "org" {
  aws_service_access_principals = ["scp.amazonaws.com"]
  feature_set                   = "ALL"
}

# MFAを強制するSCP
resource "aws_organizations_policy" "enforce_mfa" {
  name = "EnforceMFA"
  content = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "DenyAccessWithoutMFA"
        Effect    = "Deny"
        Action    = "*"
        Resource  = "*"
        Condition = {
          BoolIfExists = {
            "aws:MultiFactorAuthPresent" = "false"
          }
        }
      },
      {
        Sid    = "AllowMFAManagement"
        Effect = "Allow"
        Action = [
          "iam:CreateVirtualMFADevice",
          "iam:EnableMFADevice",
          "iam:ResyncMFADevice",
          "iam:DeleteVirtualMFADevice"
        ]
        Resource = "*"
      }
    ]
  })
}

# SCPをルートに適用
resource "aws_organizations_policy_attachment" "enforce_mfa_attachment" {
  policy_id = aws_organizations_policy.enforce_mfa.id
  target_id = aws_organizations_organization.org.roots[0].id
}

最後に

今回は、MFAが有効化されていないIAMユーザーへの対処方法についてご紹介しました。

MFAの有効化についてはログイン認証における基礎中の基礎の内容だとは思いますが、組織的にそれを強制化させる事は案外出来ていないケースも多いのではないかなと感じます。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る