AWS IAM で、セルフサービスな MFA 環境を作ってみた

# はじめに

AWS のマネージメントコンソールでは、MFA の設定が出来ます。これによってセキュリティレベルを上げることが出来ます。

一点考えないといけないのが、誰が MFA を設定するのか？という点です。AWS を使う人が小規模な場合は、一部の管理者が代わりに MFA の設定を行うことで、MFA の設定を強制化できるでしょう。AWS の利用が大規模になったときはどうでしょうか？全員分の MFA の設定を管理者が行うのは大変です。

そこで、利用者がセルフサービスで MFA の設定を出来るようにすることがのぞましいです。要件を整理するとこんな感じです

- AWS のサービスを利用するためには、強制的に MFA を有効化させたい
- 管理負担の軽減の観点で、自分自身の IAM User に、セルフサービスの MFA デバイスの紐づけを許可させたい。
- 管理者が IAM User を作成したあとに、利用者に ユーザーに ID と Password を展開するときには、**MFA の設定は入っていない。MFA 無しでも、ログインして MFA の有効化が出来る環境が必要**



この環境を実現するための IAM Policy の書き方が AWS Document で紹介されています。この設定方法を簡単に紹介していきます。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html

　

「管理者」と「利用者」の 2 つの役割にわけで、それぞれ行う作業を紹介していきます。



# 管理者 : IAM Policy の作成

セルフサービスの MFA 設定を許可するための、IAM Policy を作成します。



Create policy を押します。

![image-20221228212704018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ae213ba4-be9f-859e-bf0a-a8c875e54554.png)



IAM Policy に与える権限設定として、以下の JSON を入力します。

- `DenyAllExceptListedIfNoMFA` : の部分で、ユーザー自身による MFA 設定を許可している
- MFA に関する設定は、MFA を使っていなくても操作を許可する
- MFA を使っていないときは、EC2 や S3 といった AWS サービス群の操作を禁止している

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": [
                "iam:GetAccountPasswordPolicy",
                "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/${aws:username}"
        },
        {
            "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"
                }
            }
        }
    ]
}
```



JSON を入力したら、Next を押します。

![image-20221228212752764.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4c9f0fdc-ef24-b89b-c61e-c64da4bc82df.png)



適当にポリシー名を入れます。

![image-20221228212930399.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7624f802-6799-67b9-ef4a-870f400987f9.png)



IAM Policy が作成されました。

![image-20221228213124735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d636b29d-0c06-dbb0-438a-b2dff7f52b2a.png)



# 管理者 : IAM User を作成

上記 IAM Policy を紐づけた IAM User を作成します。より大規模な環境では、Group を作成して、全 IAM User を Group に紐づけるのが楽だと思います。

　

Add users を押します。

![image-20221228213651030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5870f4ce-ddad-0b43-cb62-ef4987b4e54c.png)

　

Require password reset は**チェックを外します**。チェック外す理由は、[こちら](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html)の Document で推奨されているためです。自分自身によるパスワードリセットは、MFA を使っている時だけ許可するようにするためです。

![image-20221228213448664.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e9c079bc-fcc5-a5e0-dc43-5c661ec3f814.png)

　

上述の通り、Require password reset の**チェックを外して**、Next を押します。

![image-20221228213240003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/13aa922c-78af-4a77-f424-7666ac7d0965.png)

　

作成した IAM Policy を指定します。

![image-20221228213825030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9e2aa6b4-f079-3115-d11f-06ea61715527.png)

　

また、AdministratorAccess も追加します。何らかの許可のポリシーがないと、何も操作ができない IAM User が出来上がります。Administrator の権限を追加した時でも、明示的な禁止のポリシーの方が優先度が高いので、MFA を設定しない状況では、何もできません。

![image-20221228215628769.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/de133fde-3d92-144d-502a-f35cb4be7988.png)



Create user を押します。

![image-20221228213849479.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e58d5c9f-1fcf-8451-b48a-0c98f9def4cf.png)

　

IAM User が作成されました。

![image-20221228213926853.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/17100ac1-6638-4f73-973f-23ef8c37f384.png)



# 利用者 : 作った IAM User でログイン

次に利用者側の視点です。管理者によって払いだされた IAM User でマネージメントコンソールにログインをします。

![image-20221228214056327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d5c4a514-9bf7-f96e-074c-c3d49ebba866.png)



ログインできました

![image-20221228214250492.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/39fec628-f012-aca9-ff53-951796f4eca2.png)



初回のログインでは MFA を使っていないので、EC2 や S3 といったサービスのページを開いても何も表示されません。

![image-20221228214333417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/12fea771-6b8e-046d-82e7-ddc6dc4087cb.png)



# 利用者 : MFA を有効化

自分自身で MFA を有効化します。IAM のページで、ダッシュボードを開き、MFA を追加のボタンを押します。いろいろエラーになっていますが、MFA を使っていないので正常な状態です。

![image-20221228214744669.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/db5b3b75-81dd-1c5c-4eb5-4506db0bb19b.png)



ちなみに、User のページから設定しようと見てみましたが、エラーで一覧も表示されませんでした。

![image-20221228214835957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/cc5881a6-9747-2565-5cfd-59a5c2fcf574.png)



AWS IAM Credentials の画面で、Assign MFA device を選びます。

![image-20221228215054336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/73563766-99e9-4e58-7741-6e6bf4313c54.png)



適当に名前を指定して、Continue を押します。

![image-20221228193722301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d795a798-fa26-ac8f-5d00-3092d4e8f356.png)



QR コードによる登録方法と、secret key による登録方法があります。どっちでもいいですが、今回は secret key でやっていきます。

![image-20221228193822547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/44c31719-ac62-d95f-95ca-541c6e9ee9ac.png)



secret key を MFA デバイスに紐づけたあと、表示される 6 桁の数字を入力します。

![image-20221228194104442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7e8f6d65-a724-190e-4a54-5412163a059a.png)

　

紐づけが出来ました。Close を押します。

![image-20221228194119935.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/aa7c43ce-7a85-d85b-cb00-c7a18460b5b3.png)

　

MFA を設定したので、一度サインアウトをします。再度ログインするときに、MFA が求められました。

![image-20221228220059456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/29a5d4d2-21b5-7971-58a5-205b9b0fcd7c.png)

　

MFA を有効化したので、EC2 などのサービスが操作できるようになりました。

![image-20221228224908528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/61d2265f-b283-bddc-3b8e-cdebae0d99dd.png)



# 検証を通じてわかったこと

- セルフサービスで MFA 設定を許可しようとすると、IAM Policy でコントロールをしていく必要がある。小規模な環境ではここまでしなくても、管理者が設定代行する方法でも良さそうに思える。
- もしくは、会社が既に使っている Okta などの Identity Provider があれば、それと連携するのが一番楽だと思う。



# 参考 URL

AWSコンソールとCLI利用時にMFA認証を必須にする
https://www.karakaram.com/requiring-mfa-authentication-when-using-aws-console-and-cli/

AWS: MFA で認証された IAM ユーザーが [My Security Credentials] (マイセキュリティ資格情報) ページで自分の認証情報を管理できるようにする
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html

AWS CLI で MFA 必須のアクセス制御を設定
https://blog.nijot.com/aws/aws-cli-mfa-force-setting/