[EC2.6] VPC flow logging should be enabled in all VPCsへの対応方法

# 概要

弊社では現在、AWS Security Hubのスコア改善に取り組んでいます。
その対応の1つでVPCフローログの設定を実施したため、その手順などをまとめます。

# VPCフローログとは

[VPCフローログ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/working-with-flow-logs.html)は、VPCのネットワークインターフェイスとの間で行き来するIPトラフィックに関する情報をキャプチャできるようにする機能のことです。

フローログデータは、Amazon CloudWatch Logs、Amazon S3、または Amazon Kinesis Data Firehose に発行できます。


トラフィックには2つのタイプがあります。

> https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-log-records.html
>
> ACCEPT ― トラフィックが承認されました。
>
> REJECT ― トラフィックが拒否されました。例えば、トラフィックがセキュリティグループまたはネットワーク ACL により許可されなかった、接続終了後にパケットが到着したなどです。

※**REJECTとは、意図しないIPからのアクセスなど、拒否されたトラフィックを指します。**

**この設定は、意図しないIPからのアクセスを検知して対策することに役立ちます。**

## 料金

ログ配信料金や保存に料金がかかります。
S3等に保存することで他に比べて保存料金は節約できます。

さらに、後述しますが今回は全てのログを保存する必要はありません。
保存対象を絞り込むことでさらに料金を抑えることができます。

また、これらの料金は例なので、実際に弊社環境でどの程度の料金がかかるかは不明です。
そこで、まずはテスト環境で料金の様子を見てから本番反映することにしました。

※REJECTに絞り込むことで、ここに記載している料金例よりもかなり安くなりました！ただしサービスの規模や設定により大きく変わると思われるので、やはり一度様子見することをお勧めします。

https://aws.amazon.com/jp/cloudwatch/pricing/

### CloudWatch Logsへの保存


>取り込まれた VPC フローログを CloudWatch Logs に 1 か月あたり 72 TB 送信する VPC をモニ>タリングし、そのデータを 1 か月間アーカイブする場合、料金は以下のようになります。
>
>**ログ取り込みの月額料金**
>0～10 TB (0.50 USD/GB) = 10 x 1,024 x 0.50 USD = 5,120.00 USD
>10～30 TB (0.25 USD/GB) = 20 x 1,024 x 0.25 USD = 5,120 USD
30～50 TB (0.10 USD/GB) = 20 x 1,024 x 0.10 USD = 2,048 USD
50～72 TB (0.05 USD/GB) = 22 x 1,024 x 0.05 USD = 1,126.40 USD
取り込みの合計料金 = 5,120 USD + 5,120 USD + 2,048 USD + 1126.40 USD = **13,414.40 USD**
>
>ログアーカイブの月額料金 (ログデータが 30 TB まで圧縮される場合)
>30 TB (0.03 USD/GB) = 30 x 1024 x 0.03 = 921.6 USD
>
>CloudWatch の月額料金 = 13,414.40 USD + 921.6 USD = **14,336 USD**


### S3への保存

> 取り込まれた VPC フローログをオプションの Apache Parquet 形式で 1 か月あたり 72 TB 直接 S3 に送信する VPC をモニタリングし、そのデータを 1 か月間アーカイブする場合、料金は以下のようになります。
>
>**ログ取り込みの月額料金**
0～10 TB (0.25 USD/GB) = 10 x 1,024 x 0.25 USD = 2,560.00 USD
10～30 TB (0.15 USD/GB) = 20 x 1,024 x 0.15 USD = 3,072.00 USD
30～50 TB (0.075 USD/GB) = 20 x 1,024 x 0.075 USD = 1,536.00 USD
50～72 TB (0.05 USD/GB) = 22 x 1,024 x 0.05 USD = 1,126.40 USD
取り込みの合計料金 = 2,560 USD + 3,072 USD + 1,536 USD + 1,126.40 USD = **8,294.40 USD**
>
>Apache Parquet 形式変換の月額料金 (オプション)
72TB (0.03 USD/GB) = 72 x 1,024 x 0.03 USD = 2,211.84 USD
>
>ログアーカイブの月額料金 (ログデータが 6.5 TB まで圧縮される場合)
6.5 TB (0.023 USD/GB) = 6.5 x 1,024 x 0.023 = 153.01 USD
>
>月額料金 = 8,294.40 USD + 153.01 USD + 2,211.84 USD = **10,659.25 USD**


# [EC2.6] VPC flow logging should be enabled in all VPCsへの対応

Security Hubの[CIS AWS Foundations Benchmark v3.0.0](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/cis-aws-foundations-benchmark.html#cis3v0-standard)のコントロールの1つとしてこの項目があり、対応の必要がありました。

## どんなコントロール？

このコントロールは、Amazon VPC Flow Logsが検出され、VPCで有効になっているかどうかをチェックします。 
Security Hubでは、VPCのパケット拒否（Reject）に対してフローログを有効にすることを推奨しています。

これによって、フローログはVPCを通過するネットワークトラフィックの可視性を提供し、異常なトラフィックを検出したり、セキュリティワークフロー中に洞察を提供したりすることができます。 

デフォルトでは、レコードには送信元、宛先、プロトコルなど、IPアドレスフローのさまざまなコンポーネントの値が含まれます。 ログフィールドの詳細と説明については、Amazon VPCユーザーガイドの[VPCフローログ](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)を参照してください。


# 対応手順

## 1. ログ保存用のS3バケット作成（一部抜粋）

```tf

locals {
  // ログ出力先にcloudwatchも使用できますが、s3の方が安いのでバケットを作成しました。
  expire_days = 任意の日数
}

resource "aws_s3_bucket" "vpc_flow_logs" {
  bucket = module.hoge.fuga.s3_bucket.vpc_flow_logs

  lifecycle {
    prevent_destroy = true // この値があるリソースを削除しようとするとエラーになります。
  }
}

resource "aws_s3_bucket_lifecycle_configuration" "vpc_flow_logs" {
  bucket = aws_s3_bucket.vpc_flow_logs.id


  rule {
    status = "Enabled"
    id     = "${local.env}_vpc_flow_logs_expire_d${local.expire_days}"

    expiration {
      days = local.expire_days
    }

    abort_incomplete_multipart_upload {
      days_after_initiation = local.expire_days
    }
  }
}

// public_access_block
// 基本的には全部true推奨
resource "aws_s3_bucket_public_access_block" "vpc_flow_logs_public_access_block" {
  bucket = aws_s3_bucket.vpc_flow_logs.id

  block_public_acls       = true
  block_public_policy     = true
  restrict_public_buckets = true
  ignore_public_acls      = true
}

// SSLでの通信のみ許可する。SecurityHubのCISv3.0.0によるチェックを通すために必要な設定
resource "aws_s3_bucket_policy" "vpc_flow_logs" {
  bucket = aws_s3_bucket.vpc_flow_logs.id

  policy = jsonencode({
    Id      = "VpcFlowLogsBucketPolicy"
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "AllowSSLRequestsOnly"
        Effect    = "Deny"
        Action    = "s3:*"
        Principal = "*"
        Resource = [
          "arn:aws:s3:::${aws_s3_bucket.vpc_flow_logs.id}",
          "arn:aws:s3:::${aws_s3_bucket.vpc_flow_logs.id}/*"
        ]
        Condition = {
          Bool = {
            "aws:SecureTransport" = "false"
          }
        }
      }
    ]
  })
}

```


## 2. フローログの作成（一部抜粋）

フローログを作成した時、S3側に自動的にフローログ用のバケットポリシーが作成されます。便利。

```tf

resource "aws_flow_log" "vpc_flow_logs_fuga_hoge_" {
  // ログを配信するS3のARN
  log_destination = data.xxx.yyy.s3.outputs.vpc_flow_logs.arn
  // ログ配信先を指定。cloud-watch-logs, s3, kinesis-data-firehose. Default: cloud-watch-logs
  // 料金を安くするためにS3を選択している。
  log_destination_type = "s3"
  // 記録するログの種類をフィルタリングする。ALL、ACCEPT、REJECT
  traffic_type = "REJECT"
  // フローログを作成するvpcのID
  vpc_id = local.vpc.id
  // フローログ名
  tags = {
    Name = "vpc_flow_logs_fuga_hoge_${local.env}"
  }
}

```


## 3. 料金の様子見

4日ほど様子見したところ、14.3MB/4日、3.575MB/日のログが保存されていました。このペースであれば30日で107MB程度だと予想できます。


![スクリーンショット 2025-03-11 20.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475547/a829959c-b32e-4abe-ae18-ffbd27933f69.png)

以下の料金表を確認し、料金を概算します。

**(0.38 + 0.025)×0.107GB/月×153.56円/$ = 6.65円/月**

※レートは計算当時のものです。

### フローログのS3への発行+保存

| **データ量** | **Vended Logs(cloudwatchへ配信)** | **Deliver Logs to S3** |
| --- | --- | --- |
| 〜10TB | $0.76 | **$0.38** |
| 10TB〜30TB | $0.38 | $0.228 |
| 30TB〜50TB | $0.152 | $0.114 |
| 50TB〜 | $0.076 | $0.076 |

### 保存されたデータ(東京リージョン)

こちらは永続的に保存しているデータに対する料金です。

| **種類** | **料金** |
| --- | --- |
| Vended Logs | $0.033/GB |
| S3 標準 〜50TB | **$0.025/GB** |
| S3 標準 50TB〜500TB | $0.024/GB |
| S3 標準 500TB〜 | $0.023/GB |
| S3 標準 – IA | $0.019/GB |

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html#flow-logs-pricing

> フローログを発行すると、提供されたログに対するデータインジェスト料金とアーカイブ料金が適用されます。提供されたログの発行に伴う料金の詳細については、「[Amazon CloudWatch 料金表](https://aws.amazon.com/cloudwatch/pricing/)」を開き、**[Logs]** (ログ) を選択して **[Vended Logs]** (提供されたログ) を参照してください。
> 
※データインジェスト・・・フローログをs3に送信

> フローログを Amazon S3 に発行すると、提供されたログに対するデータの取り込み料金とアーカイブ料金が適用されます。詳細については、「[Amazon CloudWatch 料金表](https://aws.amazon.com/cloudwatch/pricing/)」を開き、**[Logs]** (ログ) を選択して **[Vended Logs]** (提供されたログ) を参照してください。
> 

## 4. 本番環境への反映

想像よりもかなり安かったので、本番環境でも同様の対応を実施しました！