Compute EngineのShielded VMでブートレベルのセキュリティを強化する手順

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

この記事では、Google Cloud Compute EngineインスタンスでShielded VM機能が無効化されている場合のセキュリティリスクと、その有効化手順を解説します。

ポリシーの説明

Shielded VMは、Google Cloud上のVMインスタンスに対してブートレベルのセキュリティ保護を提供する機能です。この機能は、セキュアブート、vTPM(仮想Trusted Platform Module)、およびインテグリティモニタリングの3つの主要なセキュリティ機能を含みます。これらの機能により、ルートキットやブートキットなどの持続的な脅威からVMを保護し、起動時からインスタンスの完全性を確保します。

リスク

Shielded VMが無効な場合、以下のリスクが発生します:

  • ブートレベルマルウェアの脅威: ルートキットやブートキットがOSの下層に潜伏し、従来のセキュリティツールでは検出困難な攻撃を受ける可能性がある
  • 不正なOSやファームウェアの実行: 改ざんされたブートローダーやカーネルが実行され、システム全体が侵害される危険性がある
  • 暗号鍵の不適切な管理: vTPMがないため、暗号鍵やシークレットが安全に保管されず、漏洩リスクが高まる
  • ブートプロセスの改ざん検出不能: インテグリティモニタリングがないため、ブート時の改ざんを検出できず、侵害に気づくのが遅れる
  • コンプライアンス要件の不適合: 多くのセキュリティ標準やコンプライアンス要件で、ブートレベルのセキュリティが求められる場合がある

修復方法

コンソールでの修復手順

Google Cloud コンソールを使用して、Shielded VM機能を有効化します。

既存インスタンスの更新(停止が必要)

  1. 対象のインスタンスを選択し、「停止」をクリックしてインスタンスを停止します
  2. インスタンスが停止したら、「編集」をクリックします
  3. 「シールド VM」セクションまでスクロールし、以下を設定します:
    • 「vTPMを有効にする」:チェック
    • 「インテグリティモニタリングを有効にする」:チェック
    • 注意:セキュアブートは既存インスタンスでは変更できません
  4. 「保存」をクリックして変更を適用します
  5. インスタンスを再起動します

組織ポリシーでShielded VMを強制

  1. 「IAMと管理」→「組織のポリシー」に移動します
  2. 「compute.requireShieldedVm」ポリシーを検索します
  1. 「編集」をクリックし、「強制」を選択します
  2. 「保存」をクリックして組織全体に適用します

Terraformでの修復手順

Shielded VM機能を有効化するTerraformコードと、主要な修正ポイントを説明します。

# Shielded VM有効化済みのインスタンス
resource "google_compute_instance" "shielded_vm" {
  name         = "secure-shielded-instance"
  machine_type = "e2-medium"
  zone         = "asia-northeast1-a"

  boot_disk {
    initialize_params {
      # Shielded VMをサポートするイメージを使用
      # 注: Shielded VMは、サポートされているパブリックイメージが必要です
      # サポート対象: CentOS、Debian、RHEL、Ubuntu、Windows Serverなど
      image = "debian-cloud/debian-11"
      size  = 20
      type  = "pd-standard"
    }
  }

  network_interface {
    network    = google_compute_network.main.id
    subnetwork = google_compute_subnetwork.main.id

    # 外部IPを割り当てない(セキュリティベストプラクティス)
    # access_config {}
  }

  # Shielded VM設定 - すべての機能を有効化
  shielded_instance_config {
    enable_secure_boot          = true  # セキュアブート有効化
    enable_vtpm                 = true  # vTPM有効化
    enable_integrity_monitoring = true  # インテグリティモニタリング有効化
  }

  # 追加のセキュリティ設定
  metadata = {
    enable-oslogin = "TRUE"
    block-project-ssh-keys = "TRUE"
    serial-port-enable = "FALSE"  # シリアルポートを無効化
    startup-script = file("${path.module}/scripts/security-hardening.sh")
  }

  # カスタムサービスアカウント(最小権限)
  service_account {
    email  = google_service_account.shielded_instance_sa.email
    scopes = [
      "<https://www.googleapis.com/auth/logging.write>",
      "<https://www.googleapis.com/auth/monitoring.write>",
      "<https://www.googleapis.com/auth/devstorage.read_only>"
    ]
  }

  labels = {
    environment = var.environment
    security    = "shielded-vm"
  }

  tags = ["shielded-vm", "secure"]
}

# インスタンステンプレートでのShielded VM設定
resource "google_compute_instance_template" "shielded_template" {
  name_prefix  = "shielded-vm-template-"
  machine_type = "e2-medium"

  disk {
    source_image = "debian-cloud/debian-11"
    auto_delete  = true
    boot         = true
    disk_size_gb = 20
    disk_type    = "pd-standard"
  }

  network_interface {
    network    = google_compute_network.main.id
    subnetwork = google_compute_subnetwork.main.id

    # 外部IPを割り当てない(セキュリティベストプラクティス)
    # access_config {}
  }

  # Shielded VM設定
  shielded_instance_config {
    enable_secure_boot          = true
    enable_vtpm                 = true
    enable_integrity_monitoring = true
  }

  metadata = {
    enable-oslogin         = "TRUE"
    block-project-ssh-keys = "TRUE"
  }

  # カスタムサービスアカウント(最小権限)
  service_account {
    email  = google_service_account.shielded_instance_sa.email
    scopes = [
      "<https://www.googleapis.com/auth/logging.write>",
      "<https://www.googleapis.com/auth/monitoring.write>",
      "<https://www.googleapis.com/auth/devstorage.read_only>"
    ]
  }

  lifecycle {
    create_before_destroy = true
  }
}

# 組織ポリシーでShielded VMを強制
resource "google_organization_policy" "require_shielded_vm" {
  org_id     = var.organization_id
  constraint = "compute.requireShieldedVm"

  boolean_policy {
    enforced = true
  }
}

# プロジェクトレベルでの強制(代替)
resource "google_project_organization_policy" "require_shielded_vm" {
  project    = var.project_id
  constraint = "compute.requireShieldedVm"

  boolean_policy {
    enforced = true
  }
}

# マネージドインスタンスグループでの使用
resource "google_compute_instance_group_manager" "shielded_group" {
  name               = "shielded-vm-group"
  base_instance_name = "shielded-vm"
  zone               = "asia-northeast1-a"

  version {
    instance_template = google_compute_instance_template.shielded_template.id
  }

  target_size = 3

  # 自動修復ポリシー
  auto_healing_policies {
    health_check      = google_compute_health_check.shielded_health.id
    initial_delay_sec = 300
  }
}

# ヘルスチェック
resource "google_compute_health_check" "shielded_health" {
  name                = "shielded-vm-health-check"
  check_interval_sec  = 30
  timeout_sec         = 10
  healthy_threshold   = 2
  unhealthy_threshold = 3

  tcp_health_check {
    port = "22"
  }
}

# カスタムサービスアカウント
resource "google_service_account" "shielded_instance_sa" {
  account_id   = "shielded-instance-sa"
  display_name = "Shielded VM Instance Service Account"
  description  = "Service account for Shielded VM instances"
}

# 必要最小限の権限
resource "google_project_iam_member" "shielded_sa_log_writer" {
  project = var.project_id
  role    = "roles/logging.logWriter"
  member  = "serviceAccount:${google_service_account.shielded_instance_sa.email}"
}

resource "google_project_iam_member" "shielded_sa_metric_writer" {
  project = var.project_id
  role    = "roles/monitoring.metricWriter"
  member  = "serviceAccount:${google_service_account.shielded_instance_sa.email}"
}

# ネットワーク設定
resource "google_compute_network" "main" {
  name                    = "secure-network"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "main" {
  name          = "secure-subnet"
  ip_cidr_range = "10.0.0.0/24"
  region        = "asia-northeast1"
  network       = google_compute_network.main.id

  private_ip_google_access = true
}

# ファイアウォールルール(最小限のアクセス)
resource "google_compute_firewall" "shielded_ssh" {
  name    = "allow-ssh-shielded"
  network = google_compute_network.main.name

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

  source_ranges = ["35.235.240.0/20"]  # Google Cloud IAP range
  target_tags   = ["shielded-vm"]
}

 

まとめ

この記事では、Google Cloud Compute EngineインスタンスでShielded VM機能が無効化されている場合のセキュリティリスクと、その有効化手順を解説しました。Shielded VMを有効化することで、セキュアブート、vTPM、インテグリティモニタリングによるブートレベルの強固なセキュリティが実現されます。

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

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る