S3バケットのパブリックアクセス有効の検知と自動修復

## 概要

AWS認定のDOP-C02を受験するうえで、AWS Configをほとんど触ったことが無かったので概要を把握するために試しに触った際の記録。
S3バケットのパブリックアクセスを自動検知するルールがあるらしいので、そりゃ便利だということで試してみる。（TerraformのStateファイルのバックエンドの保管等にも使用するので、意図せずパブリックアクセスが有効になったりすると困るので…）

## 手順

1. 検証用のS3バケットを作成する
1. AWS Configを設定する
1. 自動修復アクションを追加する
1. パブリックアクセスを有効にして挙動を確認する

## 検証用のS3バケットを作成する

terraformで作成。モジュールは[こちら](https://github.com/terraform-aws-modules/terraform-aws-s3-bucket?ref=v4.1.2)を使用しています。

```terraform
terraform {
  backend "local" {}
  required_version = ">=1.3.7"
  required_providers {
    aws = {
      version = "5.53.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

module "general_s3_bucket" {
  source = "git::https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v4.1.2"
  bucket = "<S3-BUCKET-NAME>"
}

```

terraform applyで作成し、パブリックアクセスが無効のバケットが出来上がったことを確認する。

## AWS Configの設定

こちらの[s3-bucket-level-public-access-prohibited](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/s3-bucket-level-public-access-prohibited.html)のAWS管理ルールを使います。

すべてデフォルト値で設定をします。
まずはこの状態で、どのように検出されるかを確認します。

![スクリーンショット 2024-06-08 183643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/07759e87-a356-e358-9521-916304449c7d.png)

今回作成したS3バケットはパブリックアクセス無効なので、コンプライアンスは「準拠」になっています。

### 動作検証

では、このバケットのパブリックアクセスが有効になった際は、きちんと検出されるかを確認します。

terraformに一部パラメータを追加して、パブリックアクセスを有効にします。

```terraform
module "general_s3_bucket" {
  source               = "git::https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v4.1.2"
  bucket               = "<S3-BUCKET-NAME>"
  attach_public_policy = false # add
}
```

変更を加えます。

```terraform
Terraform will perform the following actions:

  # module.general_s3_bucket.aws_s3_bucket_public_access_block.this[0] will be destroyed
  # (because index [0] is out of range for count)
  - resource "aws_s3_bucket_public_access_block" "this" {
      - block_public_acls       = true -> null
      - block_public_policy     = true -> null
      - bucket                  = "<S3-BUCKET-NAME>" -> null
      - id                      = "<S3-BUCKET-NAME>" -> null
      - ignore_public_acls      = true -> null
      - restrict_public_buckets = true -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.
```

S3バケットのパブリックアクセスが有効になったので、Configが検出するのを待ちます。

![スクリーンショット 2024-06-08 184401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/b27c2138-9d39-2828-010c-691279c11f45.png)

数分後に、このバケットのコンプライアンスステータスが「非準拠」になっていました。想定通り、S3バケットのパブリックアクセスの設定変更を検知できているようです。

## 自動修復アクションを設定する

今回作成したルールに対して、自動修復アクションを追加します。
「アクション」->「修復の管理」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/6bb174c1-d7f0-721a-0909-24cdeaf83fb4.png)

「修復方法を選択」で「自動修復」を選択します。再試行も必要であれば設定しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/5ca51cf0-c433-0b19-716e-db788d35b567.png)

お目当てのアクションを実行してくれそうな修復アクションを発見したので、こちらを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/8aba4af1-18cd-eb93-b4a6-f189860c61f9.png)

そのまま設定を保存しようとしたらエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/8d3afb44-6508-552e-2189-e66fa8824a07.png)

どうやらSystems ManagerがS3バケットを操作するために、IAMロールを設定しておく必要があるみたいですね。今回は前工程でTerraformの実行用に使用していたIAMロールにssmに対する信頼関係ポリシーを追加して流用しました。

設定後のパラメータ一覧はこうなりました。自動修復するS3バケットの名前（リソースID）は、非準拠になったリソースのパラメータを渡します。

![スクリーンショット 2024-06-09 091919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/257f9ec5-25be-1131-1cc8-4342004f5cd0.png)

## パブリックアクセスを有効にして挙動を確認する

再度Terraformを使ってパブリックアクセスが無効のS3バケットを作成します。

```terraform
module "general_s3_bucket" {
  source               = "git::https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v4.1.2"
  bucket               = "<S3-BUCKET-NAME>"
  attach_public_policy = true
}
```

AWS Config上でも「準拠」になっていることを確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/608f7b72-8aab-2e7f-d169-f30d271278d7.png)

マネジメントコンソールからこのS3バケットの「ブロックパブリックアクセス」を意図的に「オフ」にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/9519f0c8-2de0-ff21-20c7-ae9bff462fc6.png)

この状態でしばらく待機します。

![スクリーンショット 2024-06-09 094301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/010b222c-9484-b5af-4cce-3abf4c3cbc4e.png)

自動修復アクションが開始された模様。

![スクリーンショット 2024-06-09 094417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/716e7105-7196-368e-0022-e2529182e91b.png)

正常に実行されたようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/a73b1d23-1975-2f75-f583-ddda3093f5e3.png)

マネジメントコンソール上でも「ブロックパブリックアクセス」がオンへ修復されていることを確認しました。

また、リソースのタイムライン上でも「ブロックパブリックアクセス」の設定が削除された2分後にSystems Managerによって修復されている履歴を確認することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/9e0affc7-8c7a-d4dc-01b3-dd2abb28fe66.png)

Terraformでplanコマンドを実行しても、差分なし（＝ブロックパブリックアクセスが有効）であることを確認できました。

```terraform
No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no
differences, so no changes are needed.
```

## 感想
上手に使えば意図しない変更や悪意のある変更にも耐久性のあるAWS環境を実現できる便利なサービスだと再度認識しました。こういう発見があるのも認定試験のメリットですね。