Google Cloud VPCネットワークサブネットの複数リージョン設定について

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

この記事では、VPCネットワークの単一リージョン構成に潜む重大なリスクと、マルチリージョン構成によるネットワーク分離・ディザスタリカバリの実装手順について、実際の障害事例を交えながら解説します。

ポリシーの説明

VPCネットワークにサブネットが単一リージョンのみで設定されている場合、リージョン障害時の可用性や、地理的に分散したワークロードのネットワーク分離が不十分になります。Google CloudのVPCはグローバルリソースですが、サブネットはリージョナルリソースです。複数のリージョンにサブネットを配置することで、適切なネットワークセグメンテーションと高可用性を実現できます。単一リージョン構成の場合はリージョン障害への可用性が低くなってしまうため複数リージョンでサブネットを配置する事が推奨されています。

修復方法

コンソールでの修復手順

Google Cloud コンソールを使用して、VPCネットワークにマルチリージョンのサブネットを構成します。

1. VPCネットワークページにアクセス

  • Google Cloud コンソールにログイン
  • ナビゲーションメニューから「VPCネットワーク」を選択

2. カスタムモードVPCの作成(既存VPCがデフォルトの場合)

  • 「VPCネットワークを作成」をクリック
  • 名前: production-vpc(例)
  • サブネット作成モード: 「カスタム」を選択

3. プライマリリージョンのサブネット作成

  • サブネット名: subnet-asia-northeast1
  • リージョン: asia-northeast1(東京)
  • IPアドレス範囲: 10.0.0.0/24
  • 限定公開のGoogleアクセス: 「オン」
  • フローログ: 「オン」

4. セカンダリリージョンのサブネット追加

  • 「サブネットを追加」をクリック
  • サブネット名: subnet-asia-southeast1
  • リージョン: asia-southeast1(シンガポール)
  • IPアドレス範囲: 10.1.0.0/24
  • 同様の設定を適用

5. DR用リージョンのサブネット追加

  • 「サブネットを追加」をクリック
  • サブネット名: subnet-us-west1
  • リージョン: us-west1(米国西部)
  • IPアドレス範囲: 10.2.0.0/24
  • 同様の設定を適用

6. ファイアウォールルールの設定

  • 「ファイアウォール」タブを選択
  • 必要に応じて内部通信用のルールを作成
  • 各リージョン間の通信要件に基づいて設定

7. 作成と確認

  • 「作成」をクリック
  • VPCネットワークの詳細ページで、複数リージョンにサブネットが作成されたことを確認

8. ネットワーク接続性の確認

  • 各リージョンにテスト用のVMを作成
  • ping疎通確認で内部ネットワークの接続性を検証
  • トレースルート実行でネットワーク経路を確認

Terraformでの修復手順

複数リージョンにサブネットを持つVPCネットワークを構成するTerraformコードと、主要な修正ポイントを説明します。

# ------------------ ① VPCネットワークの作成 ------------------
resource "google_compute_network" "vpc_network" {
  name                            = "production-vpc"
  auto_create_subnetworks         = false  # カスタムモードVPC
  routing_mode                    = "REGIONAL"
  project                         = var.project_id
  delete_default_routes_on_create = true   # デフォルトルートを削除
  mtu                             = 1460   # パフォーマンス最適化
}

# ------------------ ② マルチリージョンサブネット構成 ------------------
# 東京リージョン(プライマリ)
resource "google_compute_subnetwork" "subnet_tokyo" {
  name          = "subnet-asia-northeast1"
  network       = google_compute_network.vpc_network.id
  region        = "asia-northeast1"
  ip_cidr_range = "10.0.0.0/24"

  # 限定公開のGoogleアクセス有効化
  private_ip_google_access = true

  # フローログ有効化
  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }

  # GKE用のセカンダリ範囲(オプション)
  secondary_ip_range {
    range_name    = "pods"
    ip_cidr_range = "10.10.0.0/20"
  }
  secondary_ip_range {
    range_name    = "services"
    ip_cidr_range = "10.20.0.0/20"
  }

  # Stack type設定(IPv4のみ、デュアルスタック対応可能)
  stack_type = "IPV4_ONLY"
}

# シンガポールリージョン(セカンダリ)
resource "google_compute_subnetwork" "subnet_singapore" {
  name                     = "subnet-asia-southeast1"
  network                  = google_compute_network.vpc_network.id
  region                   = "asia-southeast1"
  ip_cidr_range            = "10.1.0.0/24"
  private_ip_google_access = true

  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

# 米国西部リージョン(DR用)
resource "google_compute_subnetwork" "subnet_us_west" {
  name                     = "subnet-us-west1"
  network                  = google_compute_network.vpc_network.id
  region                   = "us-west1"
  ip_cidr_range            = "10.2.0.0/24"
  private_ip_google_access = true

  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

# ------------------ ③ ファイアウォールルール ------------------
# 内部通信を許可
resource "google_compute_firewall" "allow_internal" {
  name    = "allow-internal"
  network = google_compute_network.vpc_network.name

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

  source_ranges = [
    "10.0.0.0/24",  # 東京
    "10.1.0.0/24",  # シンガポール
    "10.2.0.0/24"   # 米国西部
  ]
}

# SSH接続を許可(IAP経由)
resource "google_compute_firewall" "allow_iap_ssh" {
  name    = "allow-iap-ssh"
  network = google_compute_network.vpc_network.name

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

  # Identity-Aware Proxyの送信元IP範囲
  source_ranges = ["35.235.240.0/20"]

  target_tags = ["allow-ssh"]
}

# ------------------ ④ Cloud NATの設定(各リージョン) ------------------
# 東京リージョンのCloud Router
resource "google_compute_router" "router_tokyo" {
  name    = "router-asia-northeast1"
  network = google_compute_network.vpc_network.id
  region  = "asia-northeast1"
}

# 東京リージョンのCloud NAT
resource "google_compute_router_nat" "nat_tokyo" {
  name                               = "nat-asia-northeast1"
  router                             = google_compute_router.router_tokyo.name
  region                             = google_compute_router.router_tokyo.region
  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}

# シンガポールリージョンのCloud Router
resource "google_compute_router" "router_singapore" {
  name    = "router-asia-southeast1"
  network = google_compute_network.vpc_network.id
  region  = "asia-southeast1"
}

# シンガポールリージョンのCloud NAT
resource "google_compute_router_nat" "nat_singapore" {
  name                               = "nat-asia-southeast1"
  router                             = google_compute_router.router_singapore.name
  region                             = google_compute_router.router_singapore.region
  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
  min_ports_per_vm                   = 64    # 最小ポート数設定
  max_ports_per_vm                   = 2048  # 最大ポート数設定
  enable_endpoint_independent_mapping = true # エンドポイント独立マッピング
}

# ------------------ ⑤ Private Service Connect(推奨) ------------------
# Google APIへのプライベートアクセス
resource "google_compute_global_address" "psc_address" {
  name          = "psc-googleapis"
  purpose       = "PRIVATE_SERVICE_CONNECT"
  address_type  = "INTERNAL"
  address       = "10.255.255.254"
  prefix_length = 32
  network       = google_compute_network.vpc_network.id
}

resource "google_compute_global_forwarding_rule" "psc_forwarding_rule" {
  name                  = "psc-googleapis-all"
  target                = "all-apis"
  network               = google_compute_network.vpc_network.id
  ip_address            = google_compute_global_address.psc_address.id
  load_balancing_scheme = ""
  psc_connection_id     = var.project_id
}

# ------------------ ⑥ VPC Service Controls(オプション) ------------------
resource "google_access_context_manager_service_perimeter" "vpc_perimeter" {
  parent = "accessPolicies/${var.access_policy_id}"
  name   = "accessPolicies/${var.access_policy_id}/servicePerimeters/production_perimeter"
  title  = "Production VPC Perimeter"

  status {
    restricted_services = [
      "storage.googleapis.com",
      "bigquery.googleapis.com",
    ]

    resources = [
      "projects/${var.project_id}",
    ]

    vpc_accessible_services {
      enable_restriction = true
      allowed_services   = ["storage.googleapis.com"]
    }
  }
}

# ------------------ ⑦ 出力値 ------------------
output "vpc_network_id" {
  value = google_compute_network.vpc_network.id
}

output "subnet_ids" {
  value = {
    tokyo     = google_compute_subnetwork.subnet_tokyo.id
    singapore = google_compute_subnetwork.subnet_singapore.id
    us_west   = google_compute_subnetwork.subnet_us_west.id
  }
}

最後に

この記事では、VPCネットワークのマルチリージョン構成によるネットワーク分離の実装手順について、リスクと対策を解説しました。

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

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る