AWS検証アカウントを作成するときに実施するセキュリティ対策

社内で検証用のAWSアカウントを整備する機会があったので、記事にまとめてみました。

# 検証用のAWSアカウントで実施したこと一覧
- IAMロール権限分離（推奨）
- IAMグループによるユーザ管理（推奨）
- IP制限
- MFA強制化（推奨）
- マルチアカウント（推奨）
- 権限昇格対策その1（推奨）
- 権限昇格対策その2

# 実施項目ごとの説明
各実施項目の詳細を以下に記載していきます。

## IAMロールによる権限分離
AWSアカウントの各ユーザに権限を付与することで、クラウドサービスの操作ができるようになります。権限設定が面倒だからといって、すべてのユーザにAdministrator Access(フルアクセス権限)を与えていませんか？
全てのユーザにフルアクセス権限を付与してしまうと、セキュリティリスクのある操作(機密情報のアップロード、アクセスキーの作成)や請求情報の閲覧・操作などが可能になってしまいます。
そのため、一部のAWSアカウント管理者のみフルアクセス権限を付与し、その他は作業用のユーザとして必要最低限の権限を付与するように、役割ごとに権限を分離することが必要になります。管理者用のIAMロール、作業者用のIAMロールをそれぞれ作成して権限を分離して、それぞれのIAMユーザに対象のIAMロールにのみスイッチする権限を付与することで実現できます。![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/b6d932cc-140a-9a6e-5752-cde9ea1858ba.png)

## IAMグループによるユーザ管理
前項でIAMロールによる権限分離を説明しました。IAMロールにスイッチするためには、各ユーザにロールへのスイッチ権限を付与する必要があります。しかし、ユーザが増えればその分権限を付与や管理作業が煩雑になってしまいます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/6ff72e02-8243-b81a-a0e6-28bdedfc8154.png)

そこでIAMグループの出番です。管理者や作業者など役割ごとにユーザのグループを作成することで、グループ単位で権限の付与が可能になります。権限の修正があった場合でも、IAMグループに付与している権限を編集するだけで、IAMユーザごとに編集する必要はありません。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/d6b0d5b1-82ec-c5ab-7c89-e2b1b4bbc4c2.png)

## IP制限
社内のデータをAWSで利用する予定だったため、社用端末からのみマネジメントコンソールの操作を許可する必要がありました。社用端末が社内のプロキシを経由してインターネットアクセスを行っているため、今回は送信元IPアドレスの制限を入れることで、社用端末からのみの操作に制限しました。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/1a4db5c6-a4b7-b757-6c0a-af0af4f1fc0e.png)
以下のIAMポリシー(許可したい任意のIPアドレスを設定したもの)を、IAMユーザまたはIAMグループに付与することで実現できます。
```
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "*",
        "Resource": "*",
        "Condition": {
            "NotIpAddress": {
                "aws:SourceIp": [
                    "[許可するIPアドレス]",
                    "[許可するIPアドレス]"
                ]
            }
        }
    }
}
```
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html

## MFA強制化
社内のデータを利用するAWSアカウントであり、不正アクセスへの対策を強固にする必要がありました。そのため、MFAの設定を強制化しました。MFAを設定していないユーザはスイッチロールをできないように設定してあります。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/b6a06ed6-ca5a-55cc-4daf-3c06d836ed95.png)
以下のIAMポリシー(許可したい任意のIPアドレスを設定したもの)を、IAMユーザまたはIAMグループに付与することで実現できます。
```
{
    "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",
                "iam:GetAccessKeyLastUsed"
            ],
            "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"
            ],
            "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:GetMFADevice",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
```
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html
### 注意点
上記IAMポリシーを設定することでMFAを強制化することができますが、1つ注意点があります。
MFAを設定後一度サインアウトして、再度ログインしましょう。MFA強制ポリシーを適用している場合、MFA設定後に再度ログインしないと権限が付与されません。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/88abd60b-c78c-1b00-954e-ddbc163e02d6.png)

## マルチアカウント
AWSでは利用目的ごとにアカウントの分離を推奨しています。今回は社内データを扱うデータ検証と自己研鑽の自由な検証の2つ目的があったため、アカウントを2つに分離しました。社内データを扱うために情報漏えい対策で権限を厳しくしていたため、アカウントが1つの場合は、自己研鑽の検証の自由度を下げなくてはいけませんでいした。それぞれの目的ごとに権限の設定ができるため、1つに集約しようとせず、マルチアカウントを活用していきましょう。
- AWSアカウントが1つの場合
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/f211fd83-d549-429f-9c70-4cbc23020ede.png)
- AWSアカウントが複数ある場合
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/06eb827d-34f2-166b-c49a-f66fb3cd5250.png)

## 権限昇格対策その1
IAMユーザの作成禁止やS3のパブリックアクセス有効化禁止等、セキュリティリスクのある操作を禁止しても、IAMロールを作成する権限がある場合は、フルアクセス権限のロールを作成することで権限昇格ができてしまいます。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/1738fd0a-548d-c157-6706-b3b7688b0f51.png)
対策として、ユーザがスイッチロールできるIAMロールを制限しましょう。IAMユーザやIAMグループは想定しているIAMロールのみスイッチロールを許可するようにすることで実現できます。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/996ded3f-c7c2-c3ba-20cf-01142d896b49.png)

## 権限昇格対策その2
前項でIAMロールへのスイッチロールを制御することで権限昇格の対策を実施できると説明しましたが、もう1つ意識しておくべき権限昇格方法があります。
EC2やLambda等リソースに対して権限を付与することです。フルアクセス権限のIAMロールにスイッチすることを制御しても、EC2にフルアクセス権限のIAMロールを付与してしまえば、制限している操作も実施できてしまいます。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/972b6183-d477-e78b-9cf8-b3420ef84f39.png)
対策として、Permissions Boundaryを利用しましょう。Permissions Boundaryを利用すると、普段アタッチしているIAMポリシーとPermissions Boundaryの両方で許可されている操作のみ有効になります。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310014/76ba885a-3a42-2ce6-aca0-db81f1317822.png)
作業者に許可している権限をPermissions Boundaryポリシーとして、付与することで、権限昇格したIAMロールを作成できなくなります。以下のポリシーをIAMロールにアタッチすることで、指定のPermissions Boundaryポリシー付与を強制化できます。Permissions Boundaryポリシーが付与されていないと権限昇格はできてしまうので、必ず作業者用のIAMロールに強制ポリシーをアタッチしましょう。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:PutRolePolicy"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:PermissionsBoundary": "[Permissions BoundaryポリシーのARN]"
                }
            }
        }
    ]
}
```

# 最後に
AWSアカウントを整備する機会があったので、セキュリティ対策をブログにしてみました。追加で実施した対策があれば本ブログで更新していこうと思います。間違い等あればご指摘いただけると幸いです。
最後までご覧いただきありがとうございます！