GCP Cloud SQLのパブリックIPの無効化手順

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

この記事では、Cloud SQLインスタンスのパブリックIPアドレス使用を制限する設定手順について、リスクと対策を解説します。

ポリシーの説明

Cloud SQLインスタンスでプライベートIPのみを許可し、データベースへの直接的なインターネットアクセスを防止します。

Cloud SQLインスタンスにパブリックIPアドレスが割り当てられている場合、設定状態によってはインターネットから直接アクセス可能な状態となります。これにより、データベースが外部の攻撃者の標的になりやすくなり、不正アクセスやデータ漏洩のリスクが高まります。プライベートIPアドレスのみを使用することで、データベースへのアクセスをVPC内部に限定し、セキュリティを大幅に向上させることができます。

修復方法

※ 変更実施時はアプリケーションなどからの接続方式の変更も併せて実施してください。

コンソールでの修復手順

Google Cloud コンソールを使用して、Cloud SQLインスタンスのパブリックIPを削除し、プライベートIPを設定します。

  1. Google Cloud Consoleにログインし、SQLページに移動します。
  1. 対象のCloud SQLインスタンスを選択します。
  1. 編集をクリックして、インスタンスの設定画面を開きます。
  1. 接続セクションまでスクロールします。
  2. プライベートIPを有効にします:
    • 「プライベートIP」のチェックボックスをオンにします
    • VPCネットワークを選択します(通常は「default」またはカスタムVPC)
    • 初回の場合、「プライベートサービスアクセスの接続を割り当てる」をクリックします
    • IPアドレス範囲を割り当てます(推奨:/24以上のサブネット)
    • 「接続」をクリックして、VPCピアリングが完了するまで待ちます(約2-3分)
  3. パブリックIPを無効にします:
    • 「パブリックIP」のチェックボックスをオフにします
  4. 保存をクリックして変更を適用します。

Terraformでの修復手順

Cloud SQLインスタンスでプライベートIPのみを使用するTerraformコードと、主要な修正ポイントを説明します。

# -------------------- ① VPCとサブネット --------------------
resource "google_compute_network" "private_network" {
  name                    = "sql-private-network"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "private_subnet" {
  name          = "sql-private-subnet"
  ip_cidr_range = "10.0.0.0/24"
  region        = var.region
  network       = google_compute_network.private_network.id
}

# -------------------- ② プライベートサービスアクセス --------------------
resource "google_compute_global_address" "private_ip_address" {
  name          = "sql-private-ip-address"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.private_network.id
}

resource "google_service_networking_connection" "private_vpc_connection" {
  network                 = google_compute_network.private_network.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}

# -------------------- ③ Cloud SQLインスタンス --------------------
resource "google_sql_database_instance" "main" {
  name             = "sql-instance-${var.environment}"
  database_version = "MYSQL_8_0"
  region           = var.region

  depends_on = [google_service_networking_connection.private_vpc_connection]

  settings {
    tier = "db-n1-standard-2"

    # --- プライベートIPのみを設定 ---
    ip_configuration {
      ipv4_enabled    = false  # パブリックIPを無効化
      private_network = google_compute_network.private_network.id

      # authorized_networksは設定しない(パブリックIPが無効なため不要)
    }

    # --- その他のセキュリティ設定 ---
    backup_configuration {
      enabled                        = true
      start_time                     = "02:00"
      point_in_time_recovery_enabled = true
      transaction_log_retention_days = 7
    }

    # データベースタイプに応じたセキュリティフラグ
    # MySQL/MariaDBの場合
    database_flags {
      name  = "require_secure_transport"
      value = "on"
    }

    # 監査ログの有効化(セキュリティ監視用)
    database_flags {
      name  = "general_log"
      value = "on"
    }

    database_flags {
      name  = "log_output"
      value = "FILE"
    }

    # スロークエリログの有効化
    database_flags {
      name  = "slow_query_log"
      value = "on"
    }

    database_flags {
      name  = "long_query_time"
      value = "2"
    }

    maintenance_window {
      day          = 7  # Sunday
      hour         = 3
      update_track = "stable"
    }
  }

  deletion_protection = true
}

# -------------------- ④ データベースとユーザー --------------------
resource "google_sql_database" "database" {
  name     = "application_db"
  instance = google_sql_database_instance.main.name
}

resource "google_sql_user" "users" {
  name     = "app_user"
  instance = google_sql_database_instance.main.name
  password = var.db_password  # Secret Managerから取得することを推奨
}

# -------------------- ⑥ 変数定義の例 --------------------
variable "region" {
  description = "The GCP region for resources"
  type        = string
  default     = "asia-northeast1"
}

variable "environment" {
  description = "Environment name (dev/staging/prod)"
  type        = string
}

variable "db_password" {
  description = "Database password (store in Secret Manager)"
  type        = string
  sensitive   = true
}

# -------------------- ⑤ 出力 --------------------
output "private_ip_address" {
  value       = google_sql_database_instance.main.private_ip_address
  description = "The private IP address of the Cloud SQL instance"
}

output "connection_name" {
  value       = google_sql_database_instance.main.connection_name
  description = "The connection name of the Cloud SQL instance for proxy"
}

 

主要な修正ポイント

  1. ipv4_enabled = false: パブリックIPを完全に無効化
  2. private_network: VPCネットワークを指定してプライベートIP接続を有効化
  3. google_service_networking_connection: プライベートサービスアクセスの設定(必須)
  4. require_secure_transport: SSL/TLS接続を強制してセキュリティを強化
  5. deletion_protection = true: 誤削除防止の設定

まとめ

GCP Cloud SQLのパブリックIPを無効化し、プライベートIP接続に移行することは、データベースセキュリティの基本中の基本です。本記事で紹介した手順により、インターネットからの直接攻撃を防ぎ、コンプライアンス要件を満たしながら、安全なデータベース環境を構築できます。

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

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る