VPCフローログの有効化

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、Amazon EC2が配置されるVPCにおいて、VPCフローログが有効化されておらず、またはフィルタ設定が不十分である 状態について、そのリスクと対策を解説します。具体的には、フィルタにALL(全て)またはREJECT(却下)が選択されていないケースに焦点を当てます。

ポリシーの説明

Amazon EC2 の Security Hub コントロール – AWS Security Hub

このコントロールは、Amazon VPC フローログが見つかり、VPC に対して有効になっているかどうかをチェックします。トラフィックタイプは Reject に設定されています。アカウント内の VPC に対して VPC フローログが有効になっていない場合、コントロールは失敗します。

リスク

VPCフローログは、VPC内のネットワークインターフェースを行き来するIPトラフィックに関する情報をキャプチャする機能です。このフローログが有効になっていない、あるいは重要なトラフィック(特に拒否されたトラフィック)が記録されていない場合、以下のようなセキュリティ上の重大なリスクが発生します。

  • セキュリティインシデント検知の遅延: VPCフローログは、不正なアクセス試行、ポートスキャン、DDoS攻撃の兆候など、ネットワーク上の異常なアクティビティを特定するための重要な情報源です。ログがなければ、これらの攻撃を早期に検知することが極めて困難になります。
  • フォレンジック調査の困難さ: セキュリティインシデントが発生した場合、VPCフローログは攻撃経路、影響範囲、および漏洩した可能性のあるデータを特定するための決定的な証拠となります。ログがなければ、詳細なフォレンジック調査を実行できず、根本原因の特定や再発防止策の立案が難しくなります。
  • コンプライアンス違反: 多くの業界規制やコンプライアンス基準(例: PCI DSS、HIPAA、ISO 27001)では、ネットワークアクティビティのログ記録と監査証跡の保持が義務付けられています。VPCフローログが適切に設定されていない場合、これらのコンプライアンス要件を満たせず、監査での指摘、法的リスク、罰金につながる可能性があります。
  • ネットワークトラブルシューティングの困難さ: アプリケーション間の通信問題や接続障害が発生した場合、VPCフローログはトラフィックがどこでブロックされているか、どのセキュリティグループが原因かなどを特定する上で不可欠です。ログがなければ、問題の診断と解決に大幅な時間がかかり、システムの可用性に影響を与える可能性があります。
  • 潜在的な脅威の見落とし: 特に拒否された(REJECT)トラフィックのログがない場合、不正な接続試行やポリシー違反が頻繁に発生していても、それに気づかない可能性があります。これは、セキュリティポリシーの不備や、攻撃者がシステムの脆弱性を探している兆候を見落とすことにつながります。

対策

VPCフローログを有効化し、ALL(全てのトラフィック)または少なくともREJECT(拒否されたトラフィック)をログ記録するように設定することは、AWS環境のネットワークセキュリティ監視と監査能力を大幅に向上させるためのベストプラクティスです。

  • フローログの有効化: VPCまたは個々のネットワークインターフェースに対してVPCフローログを有効化します。ログは、Amazon S3またはAmazon CloudWatch Logsに発行できます。セキュリティと長期保存の観点から、Amazon S3への発行を推奨します。
  • フィルタリングレベルの選択: フローログのフィルタ設定で、以下のいずれかを選択します。
    • ALL (全て): 許可されたトラフィックと拒否されたトラフィックの両方を記録します。最も包括的な情報が得られるため、セキュリティ監査やトラブルシューティングに最適です。ログ量が非常に多くなる可能性があります。
    • REJECT (却下): セキュリティグループやネットワークACLによって拒否されたトラフィックのみを記録します。これは、不正なアクセス試行やネットワークポリシー違反を特定する上で非常に重要であり、ALLフィルタよりもログ量を抑えつつ、重要なセキュリティ情報を提供します。
    • ACCEPT (許可): 許可されたトラフィックのみを記録します。セキュリティインシデントの調査では不十分な場合があるため、単独での使用は推奨されません。
  • ログの保存先と保持期間: ログの保存先として指定するS3バケットのアクセス権限を適切に設定し、ログの機密性を保護します。また、組織のコンプライアンス要件に合わせて、S3のライフサイクル管理機能を利用し、ログの保持期間を設定します。
  • ログ分析と監視: VPCフローログを収集したら、それを活用してセキュリティ監視を強化します。
    • CloudWatch Logsに発行する場合: CloudWatch Logs Insightsでクエリを実行したり、メトリクスフィルターとアラームを設定して、特定の異常なトラフィックパターン(例: 拒否された接続の急増)を検知し、SNSで通知を受け取ることができます。
    • S3に発行する場合: Amazon AthenaとAmazon QuickSightを使用して、ログを分析・可視化します。これにより、ネットワークトラフィックの傾向を把握したり、セキュリティインシデントの調査を効率化したりできます。また、AWS Security HubやGuardDutyなどの他のセキュリティサービスと連携して、脅威インテリジェンスを高めることも可能です。
  • 費用とパフォーマンスの考慮: ALLフィルタは大量のログを生成するため、S3のストレージ費用やCloudWatch Logsへのデータ取り込み費用が増加する可能性があります。運用コストとセキュリティ要件のバランスを考慮し、最適なフィルタリングレベルと保存期間を決定します。

修復方法

AWSコンソールでの修復手順

AWSコンソールを使用して、VPCフローログを有効化し、フィルタ設定を行います。

  1. VPCサービスへ移動: AWSコンソールにログインし、Amazon VPC サービスを開きます。
  2. 対象のVPCを選択: 左側のナビゲーションペインで「お使いの VPC」を選択し、フローログを有効にしたいVPCを選択します。
  3. フローログの作成: VPCの詳細ページで、「アクション」ドロップダウンメニューから「フローログの作成」を選択します。
  4. フローログの詳細設定:
    • 名前: フローログに任意の名前を付けます(例: my-vpc-flow-log)。フィルター:
      • すべて (ALL)」を選択します。これにより、許可されたトラフィックと拒否されたトラフィックの両方が記録されます。または、「却下 (REJECT)」を選択します。これにより、拒否されたトラフィックのみが記録され、セキュリティ関連のイベントに焦点を当てつつログ量を抑えられます。
      送信先:
      • S3 バケットに送信」を選択することを推奨します。S3 バケット ARN: ログを保存するS3バケットのARNを入力します(例: arn:aws:s3:::my-flow-logs-bucket-12345)。S3バケットは、フローログを有効にするリージョンに存在する必要があります。必要に応じて、IAM ロールを設定します。通常、S3バケットにログを書き込むための適切な権限を持つ新しいIAMロールを自動で作成または既存のロールを選択できます。または、「CloudWatch Logs に送信」を選択し、ロググループとIAMロールを設定します。
      形式: 「AWS のデフォルト形式」を選択します。必要に応じてカスタム形式も選択できます。
  5. フローログの作成: 設定を確認し、「フローログの作成」をクリックします。 数分でログの収集が開始され、指定したS3バケットまたはCloudWatch Logsグループにフローログが発行され始めます。

Terraformでの修復手順

TerraformでVPCフローログを有効化し、フィルタ設定を行うには、aws_flow_log リソースを使用します。ログの保存先はs3_bucket_arnまたはlog_group_nameで指定します。

# (例) フローログを保存するためのS3バケット
resource "aws_s3_bucket" "flow_log_bucket" {
  bucket = "my-vpc-flow-logs-bucket-unique-12345" # グローバルで一意の名前に変更
  force_destroy = true # テスト用。本番環境ではfalseを推奨

  tags = {
    Name = "VPCFlowLogBucket"
  }
}

# S3バケットポリシー (フローログサービスがバケットに書き込めるようにする)
resource "aws_s3_bucket_policy" "flow_log_bucket_policy" {
  bucket = aws_s3_bucket.flow_log_bucket.id
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Sid       = "AWSLogDeliveryWrite"
        Effect    = "Allow"
        Principal = {
          Service = "delivery.logs.amazonaws.com"
        },
        Action    = "s3:PutObject",
        Resource  = "${aws_s3_bucket.flow_log_bucket.arn}/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
        Condition = {
          StringEquals = {
            "s3:x-amz-acl" = "bucket-owner-full-control"
          }
        }
      },
      {
        Sid       = "AWSLogDeliveryAclCheck"
        Effect    = "Allow"
        Principal = {
          Service = "delivery.logs.amazonaws.com"
        },
        Action    = "s3:GetBucketAcl",
        Resource  = aws_s3_bucket.flow_log_bucket.arn
      }
    ]
  })
}

# (例) フローログを有効にするVPC
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "main-vpc-with-flow-logs"
  }
}

# VPCフローログの設定
resource "aws_flow_log" "vpc_flow_log" {
  log_destination      = aws_s3_bucket.flow_log_bucket.arn # S3バケットを宛先とする
  log_destination_type = "s3"
  traffic_type         = "ALL" # ALL (全て) または REJECT (却下) を選択
  # traffic_type         = "REJECT" # REJECT (却下) を選択することも可能
  vpc_id               = aws_vpc.main.id # フローログを有効にするVPCのID

  # IAMロールの指定 (S3への書き込み権限を持つロール)
  # 通常、サービスにリンクされたロールが使用されるため、
  # ExplicitなIAMロールの定義は不要な場合が多い。
  # ただし、特定のユースケースでは必要になる場合があります。
  # iam_role_arn = aws_iam_role.flow_log_role.arn

  tags = {
    Name = "VPCFlowLog"
  }
}

# (オプション) フローログ用のIAMロール (CloudWatch Logsに送信する場合やS3へのカスタムロールが必要な場合)
# resource "aws_iam_role" "flow_log_role" {
#   name = "vpc-flow-log-delivery-role"
#   assume_role_policy = jsonencode({
#     Version = "2012-10-17"
#     Statement = [
#       {
#         Action = "sts:AssumeRole"
#         Effect = "Allow"
#         Principal = {
#           Service = "ec2.amazonaws.com"
#         }
#       }
#     ]
#   })
# }

# resource "aws_iam_role_policy" "flow_log_policy" {
#   name = "vpc-flow-log-delivery-policy"
#   role = aws_iam_role.flow_log_role.id
#   policy = jsonencode({
#     Version = "2012-10-17"
#     Statement = [
#       {
#         Action = [
#           "logs:CreateLogGroup",
#           "logs:CreateLogStream",
#           "logs:PutLogEvents",
#           "logs:DescribeLogGroups",
#           "logs:DescribeLogStreams",
#         ],
#         Effect = "Allow",
#         Resource = "*"
#       },
#       {
#         Action = [
#           "s3:PutObject",
#           "s3:GetBucketAcl",
#           "s3:ListBucket"
#         ],
#         Effect = "Allow",
#         Resource = [
#           "${aws_s3_bucket.flow_log_bucket.arn}",
#           "${aws_s3_bucket.flow_log_bucket.arn}/*"
#         ]
#       }
#     ]
#   })
# }

# 現在のAWSアカウント情報を取得
data "aws_caller_identity" "current" {}

上記のTerraformコードでは、aws_flow_log リソースを使用してVPCフローログを定義しています。

  • log_destination: ログの保存先S3バケットのARNを指定します。
  • log_destination_type = "s3": 宛先タイプをS3に設定します。
  • traffic_type: ここで、ログを記録するトラフィックの種類を指定します。ALL(全てのトラフィック)または REJECT(拒否されたトラフィック)を選択することがセキュリティベストプラクティスです。
  • vpc_id: フローログを有効にするVPCのIDを指定します。

S3バケットをログの保存先とする場合、S3バケットポリシー(aws_s3_bucket_policy)を適切に設定し、delivery.logs.amazonaws.com サービスプリンシパルにログ書き込み権限を付与することが重要です。

my-vpc-flow-logs-bucket-unique-12345vpc-0abc123def4567890 などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、VPCフローログを有効化し、適切なフィルタリングレベル(ALLまたはREJECT)を設定することの重要性について解説しました。VPCフローログは、AWS環境のネットワークアクティビティを可視化し、セキュリティインシデントの検知、フォレンジック調査、コンプライアンス遵守、およびネットワークトラブルシューティングに不可欠なツールです。

貴社のVPCでは、フローログが適切に有効化され、必要なトラフィックが全て記録されていますか?この機会にぜひ設定を確認・強化してみてください。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る