Access Analyzerを全リージョンで有効化してみた

# はじめに

　`Access Analyzer`は、外部エンティティと共有されているリソースを検出しますので、意図しない公開設定がないか可視化でき、セキュリティに役立ちます。
　グローバルサービスだと思っていましたがリージョン別サービスだったので、`CloudFormation`でまとめて有効化を目指します。
　なお、利用は無料です。

# Access Analyzer有効化（コンソール）

![スクリーンショット 2021-01-24 20.33.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/2ae30def-67a3-565d-3b12-25954af1af21.png)


　右上のリージョン名をご覧いただければ分かる通り、グローバルではなく`東京`と記載されていることが分かります。
　`IAM`のコンソールにあるのでグローバルだと思ってしまうかもしれませんが、リージョン別サービスです。

![スクリーンショット 2021-01-24 20.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/3bb15b32-9df3-c499-6172-6244fdb3d81a.png)

　対象リージョンは現在選択しているリージョンに固定されます。
　アナライザーを作成すると、自動的にサービスにリンクされたロールも作成されます。
　ロールの権限は以下の通りです。

```json:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketPublicAccessBlock",
        "s3:GetBucketPolicyStatus",
        "s3:GetAccountPublicAccessBlock",
        "s3:ListAllMyBuckets",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicy",
        "s3:ListAccessPoints",
        "s3:GetAccessPoint",
        "s3:GetAccessPointPolicy",
        "s3:GetAccessPointPolicyStatus",
        "iam:GetRole",
        "iam:ListRoles",
        "kms:DescribeKey",
        "kms:GetKeyPolicy",
        "kms:ListGrants",
        "kms:ListKeyPolicies",
        "kms:ListKeys",
        "ec2:DescribeVpcs",
        "ec2:DescribeVpcEndpoints",
        "ec2:DescribeByoipCidrs",
        "ec2:DescribeAddresses",
        "lambda:ListFunctions",
        "lambda:GetPolicy",
        "lambda:ListLayers",
        "lambda:ListLayerVersions",
        "lambda:GetLayerVersionPolicy",
        "sqs:GetQueueAttributes",
        "sqs:ListQueues",
        "organizations:ListAWSServiceAccessForOrganization",
        "organizations:ListDelegatedAdministrators",
        "organizations:ListRoots",
        "organizations:ListParents",
        "organizations:ListChildren",
        "organizations:ListOrganizationalUnitsForParent",
        "organizations:ListAccountsForParent",
        "organizations:ListAccounts",
        "organizations:DescribeAccount",
        "organizations:DescribeOrganization",
        "organizations:DescribeOrganizationalUnit"
      ],
      "Resource": "*"
    }
  ]
}
```

　`Access Analyzer`はリソースベースのポリシーを分析して外部エンティティと共有されているか検出するので、その分析のための権限が付与されていることが分かります。
　`Organizations`のアクションは、`Access Analyzer`の信頼ゾーンが組織にも適用できるので、その関係で必要なアクションであるから許可されているのだと思います。

![スクリーンショット 2021-01-24 20.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/b56f2133-4421-0353-51c6-8bbea745b927.png)

　アナライザーの作成が完了し、外部エンティティと共有しているリソースがあったので検出されました。

![スクリーンショット 2021-01-24 20.47.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/a4316789-04f0-76d7-a939-750d40c73236.png)

　アクションのエクスポートを行うとこのような画面になり、JSON形式でダウンロードできます。
　このリソースは外部エンティティと共有することを想定して作成したリソースなので、アーカイブ済みに移します。
　問題のないリソースをアーカイブ済みに移すことで、問題あるリソースの発見が容易になります。
　アーカイブルールを作成したら、ルールに一致する検出結果が自動的にアーカイブされるようになります。
　作成してみたところ、自動的にアーカイブ済みに移動したことを確認できました。
　今度は`CloudFormation`で作成します。

# Access Analyzer有効化（CloudFormaiton）

　まず一つのリージョンで有効化します。
　テンプレートは以下の通りです。

```yaml:
AWSTemplateFormatVersion: 2010-09-09
Description: EnableAccessAnalyzer

Parameters:
  AccountID:
    Description: Account ID to be archived
    Type: String
    MaxLength: 12
    MinLength: 12

Resources:
  AccessAnalyzer:
    Type: AWS::AccessAnalyzer::Analyzer
    Properties:
      Type: ACCOUNT
      ArchiveRules:
        - Filter:
            - Property: principal.AWS
              Eq:
                - !Ref AccountID
            - Property: isPublic
              Eq:
                - false
          RuleName: ArchiveOfTrustedID

Outputs:
  AccessAnalyzerOutput:
    Value: !Ref AccessAnalyzer
```

　`Access Analyzer`の有効化と、指定したアカウントIDと共有するリソースが検出された場合は自動的にアーカイブするアーカイブルールを作成します。
　アーカイブルールの作成は以下の公式ドキュメントとコンソールで作成した際の`CloudTrail`ログ、CLIを参考にしました。
　一番確実なのは、コンソールで自分が作成したいアーカイブルールを作成して、それをCLIで見る方法です。
　https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-reference-filter-keys.html

　なお、`Outputs`を記載しているのは単に何が出力されるのか気になったので載せているだけです。
　結果はARNが出力されました。
　`AWS::AccessAnalyzer::Analyzer`を`Ref`関数に渡すとARNが返されるので当然の結果ですが、普段`Outputs`を使っていないせいか、すぐにその答えにたどり着きませんでした。

　スタックの作成は成功しました。
　一つのリージョンで無事`Access Analyzer`を有効化できたので、今度は全リージョンに対して行います。
　まず、スタックセット作成のために、二つのIAMロールを作成します。
　作成は省略しますが、ほぼこちらの公式ドキュメント通りに行っています。

　https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-prereqs-self-managed.html

　異なる点は、ターゲットアカウント（同じアカウントなのですが）のIAMロールの権限を以下の通り小さくしているところです。

```json:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "access-analyzer:CreateArchiveRule",
                "access-analyzer:CreateAnalyzer",
                "cloudformation:*",
                "sns:*"
            ],
            "Resource": "*"
        }
    ]
}
```

　SNSを許可しているのは、スタックセット作成時に以下のようにエラーが出たからです。

![スクリーンショット 2021-01-24 23.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/7705d399-9620-b3af-f84f-8283166208f3.png)

　なぜ`SNS`が？と思いましたが、公式ドキュメントでは以下のポリシーがスタックセットが機能するための最低限のポリシーだとしています。

```yaml:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": 
               [
                 "cloudformation:*",
                 "s3:*",
                 "sns:*"
               ],
            "Resource": "*"
        }
      ]
}
```

　今までこの記載は、スタックセットで`S3`と`SNS`を作成していると思っていましたが、勘違いだったようです。
　しかし、ここで疑問なのは`S3`をポリシーに追加しなくても作成できたことです。
　`S3`の許可がないと失敗する場合があるのでしょうか。
　よく分からないのでスルーします。

　アカウント内のリージョンにデプロイするのにIAMロールを作成するのは少し不思議な感じがしますが、進めていきます。

![スクリーンショット 2021-01-24 23.01.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/8b91d8e6-8da4-fddb-30dd-75620f568d46.png)
![スクリーンショット 2021-01-24 23.01.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/360e1125-eaf2-9bfd-9764-c82c2ddd8972.png)
![スクリーンショット 2021-01-24 23.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/9723a111-f654-c5bb-4bc7-50336e03caa1.png)

　リージョンはデフォルトで無効になっているリージョン(ケープタウン、香港、バーレーン、ミラノ)以外にします。

![スクリーンショット 2021-01-24 23.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/62da130f-8436-5605-2dbd-e38667a17899.png)


　16リージョンで`Access Analyzer`を有効化できました。
　コンソールで確認してみます。
　全リージョンで有効化を確認できました。
　いつもは検証が終わったらスタックセットを削除するのですが、`Access Analyzer`は無料ですので残しておきます。

# おわりに

　`Access Analyzer`は無料で使用できるのが嬉しいですね。
　アーカイブルールの追加・削除もスタックセットで簡単にできそうなので、融通が効きそうです。
　今回は同一アカウント内の全リージョンが対象でしたが、マルチアカウントの全リージョンにも簡単に作成できそうなので、規模が大きくなるほどスタックセットの効果が発揮できそうです。