配置 SSL/TLS 证书

本页介绍了如何对实例强制使用 SSL/TLS 加密以确保所有连接均已加密。您还可以详细了解 Cloud SQL 如何使用自行管理的 SSL/TLS 证书安全地连接到 Cloud SQL 实例。

概览

当您创建实例时,Cloud SQL 会自动创建一个服务器证书。我们建议您强制所有连接使用 SSL/TLS

如需使用 SSL/TLS 证书验证客户端/服务器身份,您需要创建客户端证书并将证书下载到 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 代理Cloud SQL 连接器进行连接。如果您使用 Cloud SQL Auth 代理或 Cloud SQL 连接器进行连接,则连接会使用 SSL/TLS 自动加密。无论 SSL 模式设置如何,使用 Cloud SQL Auth 代理和 Cloud SQL 连接器还会自动验证客户端和服务器身份。

如需启用“要求使用 SSL/TLS”,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 点击 SQL 导航菜单中的连接
  4. 选择安全标签页。
  5. 从下列选项中选择一项:
    • 允许未加密的网络流量(不推荐)
    • 只允许 SSL 连接。此选项仅允许使用 SSL/TLS 加密的连接。不验证证书。
    • 需要受信任的客户端证书。此选项仅允许来自使用有效客户端证书的客户端且经过 SSL 加密的连接。 如果客户端或用户使用 IAM 数据库身份验证进行连接,则他们必须使用 Cloud SQL Auth 代理或 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 代理或 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
      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 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    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。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 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 代理或 Cloud SQL 连接器来强制执行客户端身份验证。
    • INSTANCE_ID:实例 ID

    HTTP 方法和网址:

    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 代理或 Cloud SQL 连接器来强制执行客户端身份验证。
    • INSTANCE_ID:实例 ID

    HTTP 方法和网址:

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

    请求 JSON 正文:

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

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

服务器证书

当您创建实例时,Cloud SQL 会自动创建一个服务器证书。只要此服务器证书有效,您就无需主动管理服务器证书。Cloud SQL 允许您在两种不同的证书授权机构 (CA) 层次结构之间进行选择。您选择的 CA 层次结构将成为实例的服务器 CA 模式。如果您将“按实例 CA”作为实例的服务器 CA 模式,则服务器证书的失效日期为 10 年。如果您将共享 CA 用作实例的服务器 CA 模式(预览版),则服务器证书的到期日期为 1 年。在该失效日期之后,服务器证书将失效,客户端也无法再使用该证书与您的实例建立安全连接。如果客户端配置为验证 CA 或验证服务器证书中的主机名,则该客户端与服务器证书已过期的 Cloud SQL 实例的连接将会失败。为防止客户端连接中断,请在服务器证书过期之前轮替服务器证书。系统会定期通知您服务器证书即将到期。通知在失效日期前的以下天数发送:90、30、10、2 和 1。

您可以获取服务器证书的相关信息,例如该证书的创建时间和到期时间。在到期日期之前,您可以手动创建新的付款资料。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 点击 SQL 导航菜单中的连接
  4. 选择安全标签页。
  5. 前往管理服务器证书部分。

    您可以在表中查看服务器证书的失效日期。

gcloud

对于使用自签名服务器证书的实例(实例级 CA)

  1. 如需获取服务器证书的相关信息,请使用 sql ssl server-ca-certs list 命令:
    gcloud sql ssl server-ca-certs list \
    --instance=INSTANCE_NAME
  2. 如需创建服务器证书,请使用 sql ssl server-ca-certs create 命令:
    gcloud sql ssl server-ca-certs create \
    --instance=INSTANCE_NAME
  3. 将证书信息下载到本地 PEM 文件中:
    gcloud sql ssl server-ca-certs list \
    --format="value(cert)" \
    --instance=INSTANCE_NAME > \
    FILE_PATH/FILE_NAME.pem
  4. 通过将下载的文件复制到客户端宿主机上并替换现有的 server-ca.pem 文件,将所有客户端更新为使用新信息。

对于使用共享 CA 颁发的服务器证书的实例预览版):

  1. 如需获取服务器证书的相关信息,请使用 beta sql ssl server-certs list 命令:
    gcloud beta sql ssl server-certs list \
       --instance=INSTANCE_NAME
  2. 如需创建服务器证书,请使用 beta sql ssl server-certs create 命令:
    gcloud beta sql ssl server-certs create \
       --instance=INSTANCE_NAME
  3. 将证书信息下载到本地 PEM 文件中:
    gcloud beta sql ssl server-certs list \
       --format="value(ca_cert.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 年。
  • 当客户端证书即将到期时,您不会收到通知。
  • 您的 Cloud SQL 实例必须处于运行状态才能创建 SSL 证书。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 点击 SQL 导航菜单中的连接
  4. 选择安全标签页。
  5. 点击创建客户端证书
  6. 创建客户端证书对话框中,添加一个唯一名称。
  7. 点击创建
  8. 已创建新的 SSL 证书对话框的第一部分,点击下载 client-key.pem,将私钥下载到名为 client-key.pem 的文件中。
  9. 在第二部分,点击下载 client-cert.pem,将客户端证书下载到名为 client-cert.pem 的文件中。
  10. 在第三部分,点击下载 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 方法和网址:

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

    请求 JSON 正文:

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

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

  2. 将响应中英文引号内的所有证书内容(不包括英文引号本身)复制到本地文件中,如下所示:
    1. serverCaCert.cert 复制到 server-ca.pem
    2. clientCert.cert 复制到 client-cert.pem
    3. certPrivateKey 复制到 client-key.pem

REST v1beta4

  1. 创建一个 SSL/TLS 证书,为其指定对于此实例唯一的名称:

    在使用任何请求数据之前,请先进行以下替换:

    • project-id:项目 ID
    • instance-id:实例 ID
    • client-cert-name:客户端证书名称

    HTTP 方法和网址:

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

    请求 JSON 正文:

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

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

  2. 将响应中英文引号内的所有证书内容(不包括英文引号本身)复制到本地文件中,如下所示:
    1. serverCaCert.cert 复制到 server-ca.pem
    2. clientCert.cert 复制到 client-cert.pem
    3. certPrivateKey 复制到 client-key.pem

此时,您会获得以下各项:

  • 另存为 server-ca.pem 的服务器证书。
  • 另存为 client-cert.pem 的客户端公钥证书。
  • 另存为 client-key.pem 的客户端私钥。
根据您在建立连接时所使用的工具,这三项的指定方式会有所不同。例如,使用 psql 命令行客户端建立连接时,这三个文件分别是 psql 连接字符串 sslrootcertsslcertsslkey 参数的值。如需查看使用 psql 客户端和 SSL/TLS 的连接示例,请参阅使用 psql 客户端连接

服务器身份验证简介

服务器身份验证取决于 Cloud SQL 实例的服务器证书授权机构 (CA) 层次结构配置。

如果您的实例配置为使用每个实例的 CA,则验证 CA 也验证了服务器身份,因为每个实例都有唯一的 CA。

如果您的实例配置为使用共享 CA(预览版),则必须验证主机名以及 CA,因为服务器 CA 会在实例之间共享。

如果您使用的是按实例 CA,则只能为 Private Service Connect 实例执行基于 DNS 名称的服务器身份验证。

如果您使用的是共享 CA(预览版),则可以针对所有类型的实例(即 Private Service Connect专用服务访问和公共 IP 实例)执行基于 DNS 名称的服务器身份验证。

您可以查看实例详情,了解为 Cloud SQL 实例配置了哪个 CA 层次结构。

如需了解详情,请参阅查看实例信息或下一部分:启用服务器身份验证

启用服务器身份验证

如果您选择共享 CA 作为 Cloud SQL 实例的服务器 CA 模式(预览版),我们建议您还启用服务器身份验证。使用共享 CA 作为服务器 CA 模式的实例在服务器证书的 Subject Alternative Name (SAN) 字段中包含实例 DNS 名称。您可以使用实例查找 API 获取此 DNS 名称,并将响应用作主机名进行服务器身份验证。您需要为 DNS 名称设置 DNS 解析。

如需启用服务器身份验证,请完成以下步骤:

  1. 检索 DNS 名称。

    1. 如需查看有关 Cloud SQL 实例的摘要信息(包括实例的 DNS 名称),请使用 gcloud sql instances describe 命令:

      gcloud sql instances describe INSTANCE_NAME \
        --project=PROJECT_ID

      进行以下替换:

      • INSTANCE_NAME:Cloud SQL 实例的名称
      • PROJECT_ID:包含实例的 Google Cloud 项目的 ID 或项目编号
    2. 在响应中,验证是否显示 DNS 名称。此名称采用以下模式:

      INSTANCE_UID.PROJECT_DNS_LABEL.REGION_NAME.sql.goog.
      

      例如:

      1a23b4cd5e67.1a2b345c6d27.us-central1.sql.goog.

  2. 在 DNS 区域中创建 DNS 记录。如果您要进行私密连接,请在相应虚拟私有云 (VPC) 网络的专用 DNS 区域中创建 DNS 记录。

  3. 连接到 Cloud SQL for PostgreSQL 实例时,请将 DNS 名称配置为主机名。然后,在客户端中启用服务器身份验证。

    例如,使用 psql 客户端时,请指定标志 sslmode=verify-full。其他 PostgreSQL 客户端驱动程序具有类似的配置标志。

后续步骤