SSL / TLS 証明書の構成

このページでは、SSL / TLS を使用するようにインスタンスを構成する方法について説明します。また、Cloud SQL でセルフマネージド SSL / TLS 証明書を使用して Cloud SQL インスタンスに安全に接続する方法についても説明します。

概要

Cloud SQL では、お客様がインスタンスを作成した時点で、サーバー証明書(server-ca.pem)が自動的に作成されます。すべての接続で SSL / TLS を使用することをおすすめします。

SSL / TLS 証明書を使用してクライアント / サーバーの ID を検証するには、クライアント証明書を作成し、PostgreSQL クライアント ホストマシンにダウンロードする必要があります。

インスタンスに SSL を適用する場合、インスタンスの再起動は必要ありません。 ただし、SSL / TLS 証明書を変更すると、インスタンスが自動的に再起動され、ダウンタイムが発生する可能性があります。

SSL モードの構成に対する変更は、新しい接続にのみ適用されます。SSL を適用する際に、インスタンスに暗号化されていない既存の接続がある場合、その接続は暗号化されずに維持されます。暗号化されていない接続を閉じて、すべての接続に SSL を適用するには、インスタンスを再起動する必要があります。

SSL / TLS 暗号化を適用する

SSL モードの設定を使用して、次の方法で SSL 暗号化を適用できます。

  • 非 SSL / 非 TLS 接続と SSL / TLS 接続の両方を許可します。クライアント証明書は SSL / TLS 接続では検証されません。この設定はデフォルトです。

  • SSL / TLS で暗号化された接続のみを許可します。クライアント証明書は SSL 接続では検証されません。

  • SSL / TLS で暗号化され、有効なクライアント証明書を有する接続のみを許可します。

Cloud SQL インスタンスで [非 SSL / 非 TLS 接続と SSL / TLS 接続を許可する] を選択すると、SSL / TLS 接続に加えて、暗号化されていない安全性の低い接続も承認されます。 すべての接続で SSL / TLS を必須としていない場合は、暗号化されていない接続が許可されます。このため、パブリック IP を使用してインスタンスにアクセスする場合は、すべての接続に SSL を適用することを強くおすすめします。

SSL / TLS 証明書を使用してインスタンスに直接接続することも、Cloud SQL Auth Proxy または Cloud SQL コネクタを使用して接続することもできます。 Cloud SQL Auth Proxy または Cloud SQL コネクタを使用して接続する場合、接続は SSL / TLS で自動的に暗号化されます。Cloud SQL Auth Proxy と Cloud SQL コネクタでは、SSL モードの設定に関係なく、クライアント ID とサーバー ID も自動的に検証されます。

SSL/TLS の要求を有効にするには、次の操作を行います。

コンソール

  1. Google Cloud コンソールで Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [接続] をクリックします。
  4. [セキュリティ] タブを選択します。
  5. 次のいずれかを選択します。
    • 暗号化されていないネットワーク トラフィックを許可する(非推奨)
    • SSL 接続のみを許可する。このオプションは、SSL / TLS 暗号化を使用する接続のみを許可します。証明書は検証されません。
    • 信頼できるクライアント証明書を必須にする。このオプションは、有効なクライアント証明書を使用している、SSL で暗号化されたクライアントからの接続のみを許可します。 クライアントまたはユーザーが IAM データベース認証を使用して接続する場合は、Cloud SQL Auth Proxy または Cloud SQL コネクタを使用してクライアントの身元確認を適用する必要があります。

gcloud

   gcloud sql instances patch INSTANCE_NAME \
   --ssl-mode=SSL_ENFORCEMENT_MODE
  

SSL_ENFORCEMENT_MODE は、次のいずれかのオプションに置き換えます。

  • ALLOW_UNENCRYPTED_AND_ENCRYPTED は、非 SSL / 非 TLS 接続と SSL / TLS 接続を許可します。SSL 接続の場合、クライアント証明書は検証されません。これはデフォルト値です。
  • ENCRYPTED_ONLY は、SSL / TLS で暗号化された接続のみを許可します。クライアント証明書は SSL 接続では検証されません。
  • TRUSTED_CLIENT_CERTIFICATE_REQUIRED は、SSL / TLS で暗号化され、有効なクライアント証明書を有する接続のみを許可します。 クライアントまたはユーザーが IAM データベース認証を使用して接続する場合は、Cloud SQL Auth Proxy または Cloud SQL コネクタを使用してクライアントの身元確認を適用する必要があります。
詳細については、 Cloud SQL for PostgreSQL の設定をご覧ください。

Terraform

SSL / TLS 暗号化を適用するには、Terraform リソースを使用します。

resource "google_sql_database_instance" "postgres_instance" {
  name             = "postgres-instance"
  region           = "asia-northeast1"
  database_version = "POSTGRES_14"
  settings {
    tier = "db-custom-2-7680"
    ip_configuration {
      # The following SSL enforcement options only allow connections encrypted with SSL/TLS and with
      # valid client certificates. Please check the API reference for other SSL enforcement options:
      # https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1beta4/instances#ipconfiguration
      require_ssl = "true"
      ssl_mode    = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"
    }
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally delete this instance by
  # use of Terraform whereas `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

変更を適用する

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行います。
    terraform init

    最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」というメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

変更を削除する

変更を削除するには、次の手順を行います。

  1. 削除の保護を無効にするには、Terraform 構成ファイルで deletion_protection 引数を false に設定します。
    deletion_protection =  "false"
  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、更新された Terraform 構成を適用します。
    terraform apply
  1. 次のコマンドを実行しています。プロンプトで「yes」と入力して、以前に Terraform 構成で適用されたリソースを削除します。

    terraform destroy

REST v1

  1. リクエストのデータを使用する前に、次のように置き換えます。

    • PROJECT_ID: プロジェクト ID
    • SSL_ENFORCEMENT_MODE: 以下のいずれかの方法を選択します。
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED: 非 SSL / 非 TLS 接続と SSL / TLS 接続を許可します。SSL 接続の場合、クライアント証明書は検証されません。これはデフォルト値です。
      • ENCRYPTED_ONLY: SSL / TLS で暗号化された接続のみを許可します。
      • TRUSTED_CLIENT_CERTIFICATE_REQUIRED: SSL / TLS で暗号化され、有効なクライアント証明書を有する接続のみを許可します。 クライアントまたはユーザーが IAM データベース認証を使用して接続する場合は、Cloud SQL Auth Proxy または Cloud SQL コネクタを使用してクライアントの身元確認を適用する必要があります。
    • INSTANCE_ID: インスタンス ID

    HTTP メソッドと URL:

    PATCH https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID

    リクエストの本文(JSON):

    
    {
      "settings": {
        "ipConfiguration": {"sslMode": "SSL_ENFORCEMENT_MODE"}
      }
    }
    
    

    リクエストを送信するには、次のいずれかのオプションを展開します。

    次のような JSON レスポンスが返されます。

REST v1beta4

  1. リクエストのデータを使用する前に、次のように置き換えます。

    • PROJECT_ID: プロジェクト ID
    • SSL_ENFORCEMENT_MODE: 以下のいずれかの方法を選択します。
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED: 非 SSL / 非 TLS 接続と SSL / TLS 接続を許可します。SSL 接続の場合、クライアント証明書は検証されません。これはデフォルト値です。
      • ENCRYPTED_ONLY: SSL / TLS で暗号化された接続のみを許可します。
      • TRUSTED_CLIENT_CERTIFICATE_REQUIRED: SSL / TLS で暗号化され、有効なクライアント証明書を有する接続のみを許可します。 クライアントまたはユーザーが IAM データベース認証を使用して接続する場合は、Cloud SQL Auth Proxy または Cloud SQL コネクタを使用してクライアントの身元確認を適用する必要があります。
    • INSTANCE_ID: インスタンス ID

    HTTP メソッドと URL:

    PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID

    リクエストの本文(JSON):

    
    {
      "settings": {
        "ipConfiguration": {"sslMode": "SSL_ENFORCEMENT_MODE"}
      }
    }
    
    

    リクエストを送信するには、次のいずれかのオプションを展開します。

    次のような JSON レスポンスが返されます。

サーバー証明書

Cloud SQL では、お客様がインスタンスを作成した時点で、サーバー証明書が自動的に作成されます。サーバー証明書は、有効な限り、お客様が積極的に管理する必要はありません。ただし、証明書には 10 年間の有効期限があり、期限が切れた証明書は無効になります。無効になると、クライアントは、証明書を使用してインスタンスへの安全な接続を確立できなくなります。サーバー証明書の有効期限が近づくと、繰り返し通知されます。通知は、有効期限の 90 日前、30 日前、10 日前、2 日前、前日に送信されます。

サーバー証明書に関する情報(作成日時や有効期限など)を取得できます。また、新しい証明書を手動で作成することもできます。

コンソール

  1. Google Cloud コンソールで Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [接続] をクリックします。
  4. [セキュリティ] タブを選択します。
  5. [サーバー証明書の管理] セクションまでスクロールします。

    サーバー証明書の有効期限はテーブルに表示されています。

gcloud

  1. サービス証明書に関する情報を取得します。
    gcloud beta sql ssl server-ca-certs list \
    --instance=INSTANCE_NAME
    
  2. サーバー証明書を作成します。
    gcloud beta sql ssl server-ca-certs create \
    --instance=INSTANCE_NAME
    
  3. ローカル PEM ファイルに証明書情報をダウンロードします。
    gcloud beta sql ssl server-ca-certs list \
    --format="value(cert)" \
    --instance=INSTANCE_NAME > \
    FILE_PATH/FILE_NAME.pem
    
  4. ダウンロードしたファイルをクライアント ホストマシンにコピーすることにより既存の server-ca.pem ファイルを置き換え、すべてのクライアントが新しい情報を使用するように更新します。

Terraform

サーバー証明書の情報を出力として指定するには、Terraform データソースを使用します。

  1. Terraform 構成ファイルに以下を追加します。
       data "google_sql_ca_certs" "ca_certs" {
         instance = google_sql_database_instance.default.name
       }
    
       locals {
         furthest_expiration_time = reverse(sort([for k, v in data.google_sql_ca_certs.ca_certs.certs : v.expiration_time]))[0]
         latest_ca_cert           = [for v in data.google_sql_ca_certs.ca_certs.certs : v.cert if v.expiration_time == local.furthest_expiration_time]
       }
    
       output "db_latest_ca_cert" {
         description = "Latest CA certificate used by the primary database server"
         value       = local.latest_ca_cert
         sensitive   = true
       }
       
  2. server-ca.pem ファイルを作成するには、次のコマンドを実行します。
       terraform output db_latest_ca_cert > server-ca.pem
       

クライアント証明書

新しいクライアント証明書を作成する

クライアント証明書は、インスタンスごとに 10 件まで作成できます。クライアント証明書を作成するには、Cloud SQL Admin IAM ロールが必要です。

クライアント証明書について、次の点にご留意ください。

  • 証明書の秘密鍵を紛失した場合、その秘密鍵は復元できないため、新たに秘密鍵を作成する必要があります。
  • デフォルトでは、クライアント証明書の有効期限は 10 年間です。
  • クライアント証明書の有効期限が近づいても、通知されません。
  • SSL 証明書を作成するには、Cloud SQL インスタンスが実行中の状態である必要があります。

コンソール

  1. Google Cloud コンソールで Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [接続] をクリックします。
  4. [セキュリティ] タブを選択します。
  5. [クライアント証明書を作成] をクリックします。
  6. [クライアント証明書の作成] ダイアログ ボックスで、一意の名前を追加します。
  7. [作成] をクリックします。
  8. [新しい SSL 証明書を作成しました] ダイアログ ボックスの最初のセクションで [client-key.pem をダウンロード] をクリックして、秘密鍵を client-key.pem というファイルにダウンロードします。
  9. 2 番目のセクションで、[client-cert.pem をダウンロード] をクリックして、クライアント証明書を client-cert.pem というファイルにダウンロードします。
  10. 3 番目のセクションで [server-ca.pem をダウンロード] をクリックして、サーバー証明書を server-ca.pem というファイルにダウンロードします。
  11. [閉じる] をクリックします。

gcloud

  1. ssl client-certs create コマンドを使用して、クライアント証明書を作成します。

    gcloud sql ssl client-certs create CERT_NAME client-key.pem \
    --instance=INSTANCE_NAME
    
  2. 作成した証明書の公開鍵を取得し、ssl client-certs describe コマンドを使用して client-cert.pem ファイルにコピーします。

    gcloud sql ssl client-certs describe CERT_NAME \
    --instance=INSTANCE_NAME \
    --format="value(cert)" > client-cert.pem
    
  3. instances describe コマンドを使用して、サーバー証明書を server-ca.pem ファイルにコピーします。

    gcloud sql instances describe INSTANCE_NAME \
    --format="value(serverCaCert.cert)" > server-ca.pem
    

Terraform

クライアント証明書を作成するには、Terraform リソースを使用します。

resource "google_sql_ssl_cert" "postgres_client_cert" {
  common_name = "postgres_common_name"
  instance    = google_sql_database_instance.postgres_instance.name
}

REST v1

  1. SSL / TLS 証明書を作成したうえで、このインスタンスにとって一意となる名前をその証明書に対して指定します。

    リクエストのデータを使用する前に、次のように置き換えます。

    • project-id: プロジェクト ID
    • instance-id: インスタンス ID
    • client-cert-name: クライアント証明書名

    HTTP メソッドと URL:

    POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/sslCerts

    リクエストの本文(JSON):

    {
      "commonName" : "client-cert-name"
    }
    

    リクエストを送信するには、次のいずれかのオプションを展開します。

    次のような JSON レスポンスが返されます。

  2. 以下のようにして、レスポンスのうち引用符で囲まれた証明書の内容全体(引用符そのものは除く)をローカル ファイルにコピーします。
    1. serverCaCert.certserver-ca.pem にコピーします。
    2. clientCert.certclient-cert.pem にコピーします。
    3. certPrivateKeyclient-key.pem にコピーします。

REST v1beta4

  1. SSL / TLS 証明書を作成したうえで、このインスタンスにとって一意となる名前をその証明書に対して指定します。

    リクエストのデータを使用する前に、次のように置き換えます。

    • project-id: プロジェクト ID
    • instance-id: インスタンス ID
    • client-cert-name: クライアント証明書名

    HTTP メソッドと URL:

    POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/sslCerts

    リクエストの本文(JSON):

    {
      "commonName" : "client-cert-name"
    }
    

    リクエストを送信するには、次のいずれかのオプションを展開します。

    次のような JSON レスポンスが返されます。

  2. 以下のようにして、レスポンスのうち引用符で囲まれた証明書の内容全体(引用符そのものは除く)をローカル ファイルにコピーします。
    1. serverCaCert.certserver-ca.pem にコピーします。
    2. clientCert.certclient-cert.pem にコピーします。
    3. certPrivateKeyclient-key.pem にコピーします。

この時点でお客様が保持している証明書は以下のとおりです。

  • server-ca.pem という名前で保存されたサーバー証明書。
  • client-cert.pem という名前で保存されたクライアントの公開鍵証明書。
  • client-key.pem という名前で保存されたクライアント秘密鍵。
接続に使用するツールにより、これら 3 つのアイテムの指定方法が異なります。たとえば、psql コマンドライン クライアントを使用して接続する場合、これら 3 つのファイルは、psql 接続文字列の sslrootcert パラメータ、sslcert パラメータ、および sslkey パラメータに対する値となります。psql クライアントと SSL / TLS を使用した接続の具体例については、psql クライアントを使用して接続するをご覧ください。

次のステップ