カスタマーサクセス部 佐竹です。
以前ご連絡しました「MFA デバイスを複数登録が可能となった」アナウンスに関連して「元通り1台のみの制限状態で運用したい」というご要望が寄せられましたので、これを可能とする IAM ポリシーを考案しました。
はじめに
上記のブログでも記載しております通り、2022年11月16日に発表された AWS Identity and Access Management now supports multiple multi-factor authentication (MFA) devices
というアップデートにより、root ユーザ及び IAM ユーザで複数の MFA デバイスを登録可能となりました。
このアップデート自体はポジティブなアップデートですが、エンドユーザー様からは「今まで通り1台のみに制限したい」というご要望も頂いております。
残念ながら、本アップデートは基本的には強制されており、Opt-out する方法がありません。そのため、IAM ポリシーで Deny を行うことで対応していきます。
制限に至る背景
先のブログでは、以下の通りに json を修正しました。
{ "Sid": "AllowManageOwnVirtualMFADevice", "Effect": "Allow", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice" ], "Resource": "arn:aws:iam::*:mfa/*" },
Resource": "arn:aws:iam::*:mfa/*
とすることで2台目以降の登録を可能とすることができますが、「MFA デバイスを1台しか許可したくない場合」もあります。
そのような場合は「既存のまま json の修正を行わない& IAM ユーザ名以外の登録ができない点を周知する」としていました。つまりは、以下の通りです。
{ "Sid": "AllowManageOwnVirtualMFADevice", "Effect": "Allow", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice" ], "Resource": "arn:aws:iam::*:mfa/${aws:username}" },
Resource": "arn:aws:iam::*:mfa/${aws:username}
となっているため、登録は IAM ユーザ名のみが許可されているのですが、運用上の問題が発生しました。
それは、「AdministratorAccess」や「IAMFullAccess」のように、「iam:CreateVirtualMFADevice」や「iam:DeleteVirtualMFADevice」に対して無制限の許可を有しているポリシーと併用する場合です。
「AdministratorAccess」や「IAMFullAccess」では、「iam:CreateVirtualMFADevice」の "Resource" において全て( *
)への Allow が明示的に許可されています。これはつまり、どのようなデバイス名でも MFA デバイスを登録できてしまうということです。それも、複数台登録もが可能となります。
このため、このポリシーだけでは制限として正しく機能させることができません。
もともと CLI では自由な名称が入力可能だった
AWS CLI では、本アップデートの前から MFA デバイスの名称は自由に入力が可能でした。
そのため、もとより「AdministratorAccess」や「IAMFullAccess」ではどのような名前の MFA デバイス名でも登録が可能だったのですが、マネジメントコンソールからはそれが不可能であったため「MFA デバイス名が自由に入力されてしまうことによる MFA デバイス名の重複」は潜在的な問題でした。
しかし、今回のアップデートでマネジメントコンソールに MFA デバイス名の入力欄が出てきたことで、もともと IAM ユーザ名で自動的に登録されていた MFA デバイス名が指定可能となり、結果として名称が重複してしまう可能性が高くなりました。
IAM ユーザ名以外の仮想 MFA デバイス名を禁止する IAM ポリシー
以下のポリシーを作成し、IAM エンティティにアタッチすることで対応が可能です。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowManageOwnVirtualMFADeviceCreationOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice" ], "NotResource": "arn:aws:iam::*:mfa/${aws:username}" }, { "Sid": "AllowDeactivateOwnVirtualMFADeviceOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:DeactivateMFADevice" ], "NotResource": "arn:aws:iam::*:user/${aws:username}" } ] }
IAM のポリシー名は Sid と同様に「AllowManageOwnVirtualMFADeviceCreationOnlyOwnUsername」などとしてください。
本ポリシーの解説
- 仮想 MFA デバイスを作成する権限 CreateVirtualMFADevice が、自身の IAM ユーザ名のみに制限できます
- 仮想 MFA デバイスを削除する権限 DeleteVirtualMFADevice が、自身の IAM ユーザ名のみに制限できます
- 仮想 MFA デバイスと IAM ユーザとの紐付けを解除する権限 DeactivateMFADevice が、自身の IAM ユーザ名のみに制限できます
また、このポリシーは Arn の一意制約によって同時に複数台の MFA デバイス登録も禁止できます。
iam:DeactivateMFADevice を記載する理由
かなり細かい説明なのでここから先は不要な方は解説を読み飛ばして頂いて構いません。
AWS マネジメントコンソールにおける MFA デバイスの登録と解除は以下の動きになります。
- 作成時:CreateVirtualMFADevice が実行され、IAM ユーザと自動的に紐づく
- 解除時:DeactivateMFADevice が実行され IAM ユーザとの紐付けが解除されると同時に DeleteVirtualMFADevice でデバイスが削除される
このように、作成時と削除時で、実行される API に違いがあります。
動作検証で発覚した問題その1
もし制限を「DeactivateMFADevice」なしに、以下のように書くとどうなるでしょうか?
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowManageOwnVirtualMFADeviceCreationOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice" ], "NotResource": "arn:aws:iam::*:mfa/${aws:username}" } ] }
これでも十分なように見えました。ですが、動作検証をしてみると「MFA デバイスを消せてしまった」のです。
CloudTrail を調べてみると、DeactivateMFADevice
が実行されていたことがわかりました。
MFA デバイスが削除されたのではなく、実際は IAM ユーザとの紐付けが解除されただけでした。
削除と同様に「Deactivate」をされることも避けたい、となりましたためこれに対応して以下のように修正しました。
動作検証で発覚した問題その2
修正したのが以下の json です。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowManageOwnVirtualMFADeviceCreationOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice", "iam:DeactivateMFADevice" ], "NotResource": "arn:aws:iam::*:mfa/${aws:username}" } ] }
これで完成だと考えていたのですが、動作確認するとダメでした。
このポリシーだと自身の MFA デバイスの Deactivate ができず、削除までたどり着けませんでした。
「"NotResource": "arn:aws:iam::*:mfa/${aws:username}"」と記載があるのに、何故ダメなのでしょうか?
CloudTrail を調べてみると DeactivateMFADevice
に渡される Arn は「MFA デバイス名」ではなく「IAM ユーザ名」だったのです。
そのため、「"NotResource": "arn:aws:iam::*:user/${aws:username}"」と記載する必要があることがわかりました。
そして先にご紹介しました以下の IAM ポリシーが完成しました。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowManageOwnVirtualMFADeviceCreationOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice" ], "NotResource": "arn:aws:iam::*:mfa/${aws:username}" }, { "Sid": "AllowDeactivateOwnVirtualMFADeviceOnlyOwnUsername", "Effect": "Deny", "Action": [ "iam:DeactivateMFADevice" ], "NotResource": "arn:aws:iam::*:user/${aws:username}" } ] }
以上で解説を終えます。
まとめ
「MFA デバイスを複数台登録させたくない」というご要望から「IAM ユーザの MFA デバイス名を IAM ユーザ名それ1台のみ登録が可能となるように制限する方法」を記載しました。
これを Deny による「明示的な拒否」と、「NotResource」によるリソースの除外設定を有効活用した IAM ポリシーをアタッチすることで実現しています。
本ブログが、同様の問題で困っていらっしゃるどなたかの参考になれば幸いです。
では、またお会いしましょう。
佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ
マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023-2024 Japan AWS Top Engineers/2020-2024 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。