VPCファイアウォールルールのログの有効化について

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

この記事では、VPCファイアウォールルールでログ収集機能の有効化設定手順について、リスクと対策を解説します。

ポリシーの説明

VPCファイアウォールルールのログ収集機能は、ネットワークトラフィックの可視化とセキュリティ監視に不可欠な機能です。この機能を有効化することで、許可・拒否されたトラフィックの詳細情報を記録し、セキュリティインシデントの検知、トラブルシューティング、コンプライアンス要件の充足が可能になります。

一方でファイアウォールログの有効化に伴うコストは発生します。

  1. ログ収集コスト:最初の50GBまで無料、それ以降は$0.50/GB
  2. ログ保存コスト:Cloud Loggingでの30日間保存は無料
  3. エクスポートコスト:BigQueryやCloud Storageへのエクスポートは別途課金
  4. 分析コスト:BigQueryクエリやCloud Functions実行にかかる費用

大規模環境では月額数百ドルになる可能性があるため、以下の最適化を検討してください。

  • 必要なログのみをフィルタリング
  • 適切な保持期間の設定
  • サンプリングの活用

修復方法

コンソールでの修復手順

Google Cloud コンソールを使用して、VPCファイアウォールルールでログ収集を有効化します。

前提条件

  1. 適切なIAM権限を持っていること:
    • compute.firewalls.update (ファイアウォールルール更新)
    • logging.sinks.create (ログシンク作成)
    • monitoring.alertPolicies.create (アラートポリシー作成)

手順

  1. VPCファイアウォールルール一覧の確認
    • Cloud コンソールで「VPC network」→「Firewall」に移動
    • ログが無効化されているルールを特定(「Logs」列が「Off」のもの)
  2. 個別ファイアウォールルールの編集
    • 対象のファイアウォールルールをクリック
    • 「EDIT」ボタンをクリック
    • 「Logs」セクションまでスクロール
    • 「Logs」を「On」に切り替え
    • 「SAVE」をクリック
  3. ログの保存先設定(Cloud Logging)
    • 「Logging」→「Logs Router」に移動
    • 「シンクを作成」をクリック
    • シンク名を入力(例:firewall-logs-sink)
    • 宛先を選択(Cloud Storage、BigQuery、Pub/Sub等)
    • フィルタを設定:
      resource.type="gce_firewall_rule"
      logName:"compute.googleapis.com%2Ffirewall"

       

    • 「CREATE SINK」をクリック
  4. ログ分析ダッシュボードの作成 ※ 必要に応じて作成しましょう
    • 「Monitoring」→「Dashboards」に移動
    • 「CREATE DASHBOARD」をクリック
    • ファイアウォールログ用のウィジェットを追加
    • 推奨メトリクス:
      • 拒否されたトラフィックの数(セキュリティ監視)
      • 送信元IPアドレスのトップ10(攻撃元の特定)
      • ポート別のトラフィック分布(異常なポートアクセスの検出)
      • 時系列でのトラフィック量(DDoS攻撃の検出)

Terraformでの修復手順

VPCファイアウォールルールでログ収集を有効にするTerraformコードと、主要な修正ポイントを説明します。

# ------------------ ① 基本的なファイアウォールルール(ログ有効) ------------------
resource "google_compute_firewall" "allow_https" {
  name    = "allow-https-with-logging"
  network = google_compute_network.vpc_network.name
  project = var.project_id

  # ログ収集を有効化
  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }

  allow {
    protocol = "tcp"
    ports    = ["443"]
  }

  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["https-server"]

  description = "Allow HTTPS traffic with comprehensive logging"
}

# ------------------ ② 内部通信用ファイアウォールルール ------------------
resource "google_compute_firewall" "allow_internal" {
  name    = "allow-internal-with-logging"
  network = google_compute_network.vpc_network.name
  project = var.project_id

  # ログ収集を有効化(内部通信も監視)
  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }

  allow {
    protocol = "tcp"
    ports    = ["0-65535"]
  }

  allow {
    protocol = "udp"
    ports    = ["0-65535"]
  }

  allow {
    protocol = "icmp"
  }

  source_ranges = [var.vpc_cidr]

  description = "Allow internal VPC communication with logging"
}

# ------------------ ③ 拒否ルール(セキュリティ監視用) ------------------
resource "google_compute_firewall" "deny_suspicious_ports" {
  name     = "deny-suspicious-ports"
  network  = google_compute_network.vpc_network.name
  project  = var.project_id
  priority = 1000

  # 拒否ルールこそログが重要
  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }

  deny {
    protocol = "tcp"
    ports    = ["135", "139", "445", "1433", "3389", "5900", "5985", "5986"]
  }

  source_ranges = ["0.0.0.0/0"]

  description = "Deny commonly exploited ports with detailed logging"
}

# ------------------ ④ ログエクスポート設定(BigQuery) ------------------
resource "google_logging_project_sink" "firewall_logs_sink" {
  name        = "firewall-logs-to-bigquery"
  project     = var.project_id
  destination = "bigquery.googleapis.com/projects/${var.project_id}/datasets/${google_bigquery_dataset.firewall_logs.dataset_id}"

  # ファイアウォールログのみをフィルタ
  filter = <<EOF
resource.type="gce_firewall_rule"
logName:"compute.googleapis.com%2Ffirewall"
EOF

  unique_writer_identity = true
}

# BigQueryデータセット
resource "google_bigquery_dataset" "firewall_logs" {
  dataset_id                  = "firewall_logs"
  project                     = var.project_id
  friendly_name               = "VPC Firewall Logs"
  description                 = "Dataset for storing VPC firewall logs"
  location                    = var.region
  default_table_expiration_ms = 2592000000  # 30日

  access {
    role          = "OWNER"
    user_by_email = var.admin_email
  }

  access {
    role           = "WRITER"
    user_by_email  = google_logging_project_sink.firewall_logs_sink.writer_identity
  }
}

# ------------------ ⑤ ログベースメトリクスの作成(事前準備) ------------------
resource "google_logging_metric" "firewall_denied_connections" {
  name        = "firewall_denied_connections"
  project     = var.project_id
  description = "Count of denied connections in firewall logs"

  filter = <<EOF
resource.type="gce_firewall_rule"
jsonPayload.rule_details.action="DENY"
EOF

  metric_descriptor {
    metric_kind = "DELTA"
    value_type  = "INT64"

    labels {
      key         = "rule_name"
      value_type  = "STRING"
      description = "The name of the firewall rule"
    }
  }

  label_extractors = {
    "rule_name" = "EXTRACT(resource.labels.firewall_rule_id)"
  }
}

# ------------------ ⑥ アラート設定(異常検知) ------------------
resource "google_monitoring_alert_policy" "firewall_denied_traffic" {
  display_name = "High Volume of Denied Traffic"
  project      = var.project_id
  combiner     = "OR"

  depends_on = [google_logging_metric.firewall_denied_connections]

  conditions {
    display_name = "Firewall Denied Traffic Rate"

    condition_threshold {
      filter = <<EOF
resource.type="global"
metric.type="logging.googleapis.com/user/${google_logging_metric.firewall_denied_connections.name}"
EOF

      duration   = "300s"
      comparison = "COMPARISON_GT"

      threshold_value = 1000  # 5分間で1000件以上の拒否

      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]

  alert_strategy {
    auto_close = "1800s"
  }
}

# ------------------ ⑥ ログ分析用のCloud Functionデプロイ(オプション) ------------------
# 注意: Cloud Functions第2世代の使用を推奨
resource "google_cloudfunctions2_function" "analyze_firewall_logs" {
  name        = "analyze-firewall-logs"
  project     = var.project_id
  location    = var.region

  build_config {
    runtime     = "python311"
    entry_point = "analyze_logs"
    source {
      storage_source {
        bucket = google_storage_bucket.functions_bucket.name
        object = google_storage_bucket_object.function_code.name
      }
    }
  }

  service_config {
    max_instance_count = 100
    available_memory   = "256M"
    timeout_seconds    = 60

    environment_variables = {
      PROJECT_ID = var.project_id
      DATASET_ID = google_bigquery_dataset.firewall_logs.dataset_id
    }
  }

  event_trigger {
    trigger_region = var.region
    event_type     = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic   = google_pubsub_topic.firewall_logs.id
  }

}

# ------------------ ⑦ 既存ルールの更新用スクリプト ------------------
# 注意: このリソースはTerraformで管理されていない既存のファイアウォールルールも更新します
# 本番環境では慎重に使用し、必要に応じて特定のルールのみを対象にしてください
resource "null_resource" "enable_logging_existing_rules" {
  provisioner "local-exec" {
    command = <<EOF
#!/bin/bash
# 既存のファイアウォールルールにログを有効化するスクリプト
PROJECT_ID="${var.project_id}"

# Terraformで管理されていないルールのみを対象にする場合は、
# 以下のようにタグやラベルでフィルタリングすることを推奨
# RULES=$(gcloud compute firewall-rules list --project=$PROJECT_ID --filter="NOT labels.managed_by:terraform" --format="value(name)")

# すべてのファイアウォールルールを取得
RULES=$(gcloud compute firewall-rules list --project=$PROJECT_ID --format="value(name)")

# 各ルールでログを有効化
for RULE in $RULES; do
  echo "Enabling logging for rule: $RULE"
  gcloud compute firewall-rules update $RULE \
    --enable-logging \
    --logging-metadata=include-all \
    --project=$PROJECT_ID || echo "Failed to update rule: $RULE"
done
EOF
  }

  # 初回実行時のみ実行する場合は以下のコメントを解除
  # triggers = {
  #   initial_run = "1"
  # }
}

# ------------------ ⑧ ログ保持ポリシー ------------------
resource "google_project_iam_custom_role" "log_retention_manager" {
  role_id     = "logRetentionManager"
  title       = "Log Retention Manager"
  description = "Manage firewall log retention policies"
  project     = var.project_id

  permissions = [
    "logging.buckets.get",
    "logging.buckets.update",
    "resourcemanager.projects.get"
  ]
}

 

最後に

この記事では、GCP VPCファイアウォールルールでログ収集機能を有効化し、ネットワークトラフィックを分析する方法について解説しました。

ファイアウォールルールのログは、セキュリティ監視とトラブルシューティングに不可欠な情報源です。すべてのファイアウォールルールでログを有効化し、適切に分析することで、セキュリティインシデントの早期検知と対応が可能になります。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る