VTRyo Blog

一歩ずつ前に進むブログ

AWSのIAMユーザにMFA設定を強制する方法

f:id:vtryo:20180801132834p:plain

ども。セキュリティ周りも担当するマンのRyoです。

スタートアップだと色々任せてくれるのでやはり楽しいですね。

AWSのセキュリティ状態、大丈夫ですか?

AWSはマネージドでセキュリティ関係をやってくれる便利なリソースがあります。

  • WAF
  • GuardDuty
  • Trusted Advisor

このあたり利用して、DDos攻撃対策や脅威検知をしています。

ただ、僕も言われて気づいたのですが「セキュリティって攻撃とか脅威だけじゃないよね?足元も確認しような」です。

今回はIAMなどの操作を理解している前提でお話していきます。

IAMユーザがMFA設定をしていない

IAMグループで最強権限を持っているAdministratorのメンバーの一部でMFA(Multi Factor Authentication)設定をしていない方がいました。

忙しかったりやろうと思っていたままそのまま…なんてことよくあることです(こればかりは仕方ない)

ということで、MFA設定しないとAWSの操作権限が付与されないようにポリシーを設定しました。

MFAの設定を強制する

IAMポリシーの作成

f:id:vtryo:20180801130416p:plain

ポリシーを作成します。 このままコピペしても問題ありません。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAllUsersToListAccounts",
            "Effect": "Allow",
            "Action": [
                "iam:ListAccountAliases",
                "iam:ListUsers",
                "iam:ListVirtualMFADevices",
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:CreateAccessKey",
                "iam:CreateLoginProfile",
                "iam:DeleteAccessKey",
                "iam:DeleteLoginProfile",
                "iam:GetLoginProfile",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey",
                "iam:UpdateLoginProfile",
                "iam:ListSigningCertificates",
                "iam:DeleteSigningCertificate",
                "iam:UpdateSigningCertificate",
                "iam:UploadSigningCertificate",
                "iam:ListSSHPublicKeys",
                "iam:GetSSHPublicKey",
                "iam:DeleteSSHPublicKey",
                "iam:UpdateSSHPublicKey",
                "iam:UploadSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:ListVirtualMFADevices",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice",
                "iam:ListAccountAliases",
                "iam:ListUsers",
                "iam:ListSSHPublicKeys",
                "iam:ListAccessKeys",
                "iam:ListServiceSpecificCredentials",
                "iam:ListMFADevices",
                "iam:GetAccountSummary",
                "sts:GetSessionToken",
                "iam:CreateLoginProfile",
                "iam:ChangePassword"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
  • ユーザーは自分のユーザー、パスワード、アクセスキー、署名証明書、SSH パブリックキー、および MFA 情報を IAM コンソールで管理できる
  • ユーザーが各自の MFA デバイスをプロビジョニングまたは管理することを許可
  • MFA を使用してユーザーがサインインした場合に限り、ユーザーが自分の MFA デバイスのみを無効化。これにより、他者がアクセスキー (MFA デバイスではない) のみを使用して MFA デバイスを無効化し、それを自分のアクセスキーと置き換えることはできない
  • ユーザーが MFA でサインインしていない場合、"Deny" と "NotAction" の組み合わせを使用して、他のすべての AWS サービスのすべてのアクションを拒否
  • サインインとパスワードの変更を許可(パスワード期限切れなどに対応)

任意の名前をつけて、付与したいIAMグループなどにアタッチします。

ポリシーのテスト

私は適当にポリシー検証用のユーザを作成しました。

MFAを設定していないユーザがログインすると、こんな感じで見えます。
意図した通りリソースの閲覧権限もない状態ですね。

f:id:vtryo:20180801131304p:plain

その後、MFAを設定しなおします。

私は仮想MFAで、Google Authenticatorを使って認証しています。*1

f:id:vtryo:20180801131911p:plain

その後再ログインすると、見れるようになっていますね!

f:id:vtryo:20180801131625p:plain

おわりに

本当はIAMユーザログイン時に「MFA設定をしてください」みたいなアナウンスとともに設定できればいいんですけど、それはできないっぽいですね。

大事故が起こる前に、IAMには適切に権限周りの設定をしていきましょう。

参考

*1:この場合、スマホがないと認証できないのである意味ハードウェアMFAでは、という声も