Compute Engine OS Loginの有効化について

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

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

ポリシーの説明

OS Loginは、Google CloudのIAMと統合されたSSHアクセス管理機能で、従来の静的なSSHキー管理方式に代わるセキュアなソリューションです。

OS Loginの主な特徴:

  • IAM統合: Google Cloud IAMでLinuxインスタンスへのアクセス権限を一元管理
  • 自動キー管理: SSHキーの生成、配布、ローテーションが自動化
  • POSIXアカウント自動作成: LinuxユーザーアカウントがGoogleアカウントに基づいて自動作成
  • 監査ログの完全性: すべてのSSHアクセスがCloud Audit Logsに記録
  • 2要素認証サポート: Googleアカウントの2FA設定がSSHアクセスにも適用

修復方法

コンソールでの修復手順

Google Cloud コンソールを使用して、OS Loginを有効化します。

  1. プロジェクトレベルでの有効化
    • Google Cloud Consoleにログインし、「Compute Engine」→「メタデータ」に移動します
    • 「メタデータ」タブで「編集」をクリックします
    • 「メタデータを追加」をクリックし、以下を設定します:
      • キー: enable-oslogin
      • 値: TRUE
    • 「保存」をクリックして変更を適用します
  2. 個別インスタンスでの有効化
    • 「Compute Engine」→「VMインスタンス」に移動します
    • 対象のインスタンスを選択し、「編集」をクリックします
    • 「カスタムメタデータ」セクションまでスクロールします
    • 「項目を追加」をクリックし、以下を設定します:
      • キー: enable-oslogin
      • 値: TRUE
    • 「保存」をクリックして変更を適用します
  3. 組織ポリシーの設定(推奨)
    • 「IAMと管理」→「組織のポリシー」に移動します
    • 「compute.requireOsLogin」ポリシーを選択し、「編集」をクリック
    • 「強制」を選択して組織全体でOS Loginを義務化
  4. IAM権限の設定
    • 「IAMと管理」→「IAM」に移動します
    • ユーザーまたはグループに以下の役割を付与します:
      • roles/compute.osLogin: 通常のSSHアクセス用
      • roles/compute.osAdminLogin: sudo権限付きアクセス用
    • ベストプラクティス:
      • 個別ユーザーではなくグループに権限を付与
      • 最小権限の原則に基づき、必要なユーザーのみにosAdminLoginを付与

Terraformでの修復手順

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

# プロジェクトレベルでOS Loginを有効化
resource "google_compute_project_metadata_item" "oslogin" {
  key   = "enable-oslogin"
  value = "TRUE"
}

# 2要素認証付きOS Loginを有効化(より高いセキュリティ)
resource "google_compute_project_metadata_item" "oslogin_2fa" {
  key   = "enable-oslogin-2fa"
  value = "TRUE"
}

# ゲスト属性管理を有効化(外部ユーザーの招待時に有用)
resource "google_compute_project_metadata_item" "oslogin_guest_attributes" {
  key   = "enable-guest-attributes"
  value = "TRUE"
}

# 組織ポリシーでOS Loginを強制
resource "google_organization_policy" "require_oslogin" {
  org_id     = var.organization_id
  constraint = "compute.requireOsLogin"

  boolean_policy {
    enforced = true
  }
}

# 組織ポリシーでShielded VMを強制(OS Loginと併用推奨)
resource "google_organization_policy" "require_shielded_vm" {
  org_id     = var.organization_id
  constraint = "compute.requireShieldedVm"

  boolean_policy {
    enforced = true
  }
}

# インスタンステンプレートでの設定
resource "google_compute_instance_template" "oslogin_enabled" {
  name_prefix  = "oslogin-enabled-template-"
  machine_type = "e2-medium"

  disk {
    source_image = "debian-cloud/debian-11"
    auto_delete  = true
    boot         = true
  }

  network_interface {
    network = google_compute_network.main.id
    subnetwork = google_compute_subnetwork.main.id
    # 外部IPを割り当てない(セキュリティベストプラクティス)
    # access_config {}
  }

  # OS Loginを有効化
  metadata = {
    enable-oslogin = "TRUE"
    # プロジェクトSSHキーもブロック(推奨)
    block-project-ssh-keys = "TRUE"
    # シリアルポートを無効化(セキュリティ強化)
    serial-port-enable = "FALSE"
  }

  service_account {
    email  = google_service_account.instance_sa.email
    scopes = ["cloud-platform"]
  }

  # Shielded VMも有効化(推奨)
  shielded_instance_config {
    enable_secure_boot          = true
    enable_vtpm                 = true
    enable_integrity_monitoring = true
  }

  lifecycle {
    create_before_destroy = true
  }
}

# 既存インスタンスでOS Loginを有効化
resource "google_compute_instance" "oslogin_instance" {
  name         = "secure-oslogin-instance"
  machine_type = "e2-medium"
  zone         = "asia-northeast1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }

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

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

  service_account {
    email  = google_service_account.instance_sa.email
    scopes = ["cloud-platform"]
  }
}

# IAMバインディング - OS Loginアクセス権限
resource "google_project_iam_binding" "oslogin_users" {
  project = var.project_id
  role    = "roles/compute.osLogin"

  members = [
    "<group:developers@example.com>",
    "<user:alice@example.com>",
  ]
}

# IAMバインディング - 管理者権限付きOS Loginアクセス
resource "google_project_iam_binding" "osadmin_login_users" {
  project = var.project_id
  role    = "roles/compute.osAdminLogin"

  members = [
    "<group:admins@example.com>",
    "<user:bob@example.com>",
  ]
}

# サービスアカウントの作成
resource "google_service_account" "instance_sa" {
  account_id   = "oslogin-instance-sa"
  display_name = "OS Login Enabled Instance Service Account"
  description  = "Service account for instances with OS Login enabled"
}

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

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

# カスタムロールでより細かい制御
resource "google_project_iam_custom_role" "oslogin_custom" {
  role_id     = "osLoginCustomRole"
  title       = "Custom OS Login Role"
  description = "Custom role for OS Login with specific permissions"
  permissions = [
    "compute.instances.get",
    "compute.instances.osLogin",
    "compute.projects.get",
  ]
}

# ネットワーク設定(参考)
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 Google Accessも有効化
  private_ip_google_access = true
}

# ファイアウォールルール(SSH用)
resource "google_compute_firewall" "oslogin_ssh" {
  name    = "allow-oslogin-ssh"
  network = google_compute_network.main.name

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

  # セキュリティ強化:ソースIPを制限
  source_ranges = [
    "203.0.113.0/24",    # 会社のIPレンジ
    "198.51.100.0/24"    # VPNゲートウェイ
  ]
  target_tags   = ["oslogin-enabled"]

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

# Identity-Aware Proxy (IAP) を使用した安全なSSH接続(推奨)
resource "google_compute_firewall" "allow_iap_ssh" {
  name    = "allow-iap-ssh"
  network = google_compute_network.main.name

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

  # IAPのソースIPレンジ
  source_ranges = ["35.235.240.0/20"]
  target_tags   = ["oslogin-enabled"]
}

 

まとめ

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

特に、複数のチームがインスタンスにアクセスする環境や、厳格なコンプライアンス要件がある環境では、OS Loginの導入は必須と言えます。

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

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る