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

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、 「どうやって直すのか?」 という具体的な修復手順(コンソール、gcloud CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、VPCファイアウォールルールでログ収集機能の有効化設定手順について、リスクと対策を解説します。

ポリシーの説明
VPCファイアウォールルールのログ収集機能は、ネットワークトラフィックの可視化とセキュリティ監視に不可欠な機能です。この機能を有効化することで、許可・拒否されたトラフィックの詳細情報を記録し、セキュリティインシデントの検知、トラブルシューティング、コンプライアンス要件の充足が可能になります。
一方でファイアウォールログの有効化に伴うコストは発生します。
- ログ収集コスト:最初の50GBまで無料、それ以降は$0.50/GB
- ログ保存コスト:Cloud Loggingでの30日間保存は無料
- エクスポートコスト:BigQueryやCloud Storageへのエクスポートは別途課金
- 分析コスト:BigQueryクエリやCloud Functions実行にかかる費用
大規模環境では月額数百ドルになる可能性があるため、以下の最適化を検討してください。
- 必要なログのみをフィルタリング
- 適切な保持期間の設定
- サンプリングの活用
修復方法
コンソールでの修復手順
Google Cloud コンソールを使用して、VPCファイアウォールルールでログ収集を有効化します。
前提条件
- 適切なIAM権限を持っていること:
compute.firewalls.update
(ファイアウォールルール更新)logging.sinks.create
(ログシンク作成)monitoring.alertPolicies.create
(アラートポリシー作成)
手順
- VPCファイアウォールルール一覧の確認
- Cloud コンソールで「VPC network」→「Firewall」に移動
- ログが無効化されているルールを特定(「Logs」列が「Off」のもの)
- 個別ファイアウォールルールの編集
- 対象のファイアウォールルールをクリック
- 「EDIT」ボタンをクリック
- 「Logs」セクションまでスクロール
- 「Logs」を「On」に切り替え
- 「SAVE」をクリック
- ログの保存先設定(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」をクリック
- ログ分析ダッシュボードの作成 ※ 必要に応じて作成しましょう
- 「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機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。