設定安全資料傳輸層 (SSL)/傳輸層安全標準 (TLS) 憑證

本頁面說明如何為執行個體強制執行 SSL/TLS 加密,確保所有連線都經過加密。您也可以進一步瞭解 Cloud SQL 如何使用自行管理的 SSL/TLS 憑證,安全地連線至 Cloud SQL 執行個體。

總覽

建立執行個體時,Cloud SQL 會自動建立伺服器憑證。建議您強制所有連線使用 SSL/TLS

只有在用戶端要求明確指定需要加密連線時,SQL Server 才會執行憑證驗證。在這種情況下,必須在用戶端電腦上安裝伺服器憑證。否則,即使您將執行個體的 sslMode 設為 ENCRYPTED_ONLY,用戶端仍可自由連線,無須對連線字串或憑證進行額外變更。

詳情請參閱 SQL Server 說明文件中的「啟用資料庫引擎的加密連線」一節。

如果您強制執行個體使用 SSL,則必須重新啟動執行個體。 變更 SSL/TLS 憑證後,可能也需要重新啟動。 如果需要重新啟動,Cloud SQL 會自動重新啟動執行個體。 重新啟動執行個體可能會導致系統停機。

強制執行 SSL/TLS 加密機制

您可以透過 SSL 模式設定,以以下方式強制執行 SSL 加密:

  • 允許非 SSL/非 TLS 和 SSL/TLS 連線。這是目前的預設做法。

  • 僅允許透過 SSL/TLS 加密的連線。

如果您為 Cloud SQL 執行個體選取「允許非 SSL/非 TLS 和 SSL/TLS 連線」,系統會接受 SSL/TLS 連線,以及未加密和不安全的連線。如果您不需要針對所有連線使用安全資料傳輸層 (SSL)/傳輸層安全標準 (TLS),系統仍會允許未加密的連線。因此,如果您要使用公開 IP 存取執行個體,強烈建議您針對所有連線強制執行 SSL。

您可以透過 SSL/TLS 憑證直接連線至執行個體,也可以使用 Cloud SQL 驗證 ProxyCloud SQL 連接器連線。如果您使用 Cloud SQL 驗證 Proxy 或 Cloud SQL 連接器連線,系統會自動以 SSL/TLS 加密連線。無論 SSL 模式設定為何,Cloud SQL 驗證 Proxy 和 Cloud SQL 連接器也會自動驗證用戶端和伺服器身分。

強制執行 SSL 可確保所有連線都經過加密。

如要啟用 SSL/TLS 需求,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。

    前往 Cloud SQL 執行個體

  2. 如要開啟執行個體的「總覽」頁面,請按一下執行個體名稱。
  3. 按一下 SQL 導覽選單中的「連線」
  4. 選取「安全性」分頁標籤。
  5. 選取下列其中一個選項:
    • 允許未加密的網路流量 (不建議)
    • 僅允許 SSL 連線。這個選項只允許使用 SSL/TLS 加密的連線。
   gcloud sql instances patch INSTANCE_NAME \
   --ssl-mode=SSL_ENFORCEMENT_MODE
  

請使用下列其中一個選項取代 SSL_ENFORCEMENT_MODE

  • ALLOW_UNENCRYPTED_AND_ENCRYPTED 允許非 SSL/非 TLS 和 SSL/TLS 連線。這是預設值。
  • ENCRYPTED_ONLY 只允許透過 SSL/TLS 加密的連線。

如要強制執行 SSL/TLS 加密,請使用 Terraform 資源

resource "google_sql_database_instance" "sqlserver_instance" {
  name             = "sqlserver-instance"
  region           = "asia-northeast1"
  database_version = "SQLSERVER_2019_STANDARD"
  root_password    = "INSERT-PASSWORD-HERE"
  settings {
    tier = "db-custom-2-7680"
    ip_configuration {
      ssl_mode = "ENCRYPTED_ONLY"
    }
  }
  # 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 顯示「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
  1. 使用任何要求資料之前,請先替換以下項目:

    • PROJECT_ID:專案 ID
    • SSL_ENFORCEMENT_MODE:使用下列其中一個選項:
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED:允許非 SSL/非 TLS 和 SSL/TLS 連線。
      • ENCRYPTED_ONLY:僅允許使用 SSL/TLS 加密的連線。
    • INSTANCE_ID:執行個體 ID

    HTTP 方法和網址:

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

    JSON 要求主體:

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

    如要傳送要求,請展開以下其中一個選項:

    將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

    curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID"

    將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method PATCH `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID" | Select-Object -Expand Content

    您應該會收到如下的 JSON 回應:

    {
      "kind": "sql#operation",
      "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
      "status": "PENDING",
      "user": "user@example.com",
      "insertTime": "2020-01-20T21:30:35.667Z",
      "operationType": "UPDATE",
      "name": "OPERATION_ID",
      "targetId": "INSTANCE_ID",
      "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
      "targetProject": "PROJECT_ID"
    }
    
  1. 使用任何要求資料之前,請先替換以下項目:

    • PROJECT_ID:專案 ID
    • SSL_ENFORCEMENT_MODE:使用下列其中一個選項:
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED:允許非 SSL/非 TLS 和 SSL/TLS 連線。
      • ENCRYPTED_ONLY:僅允許使用 SSL/TLS 加密的連線。
    • INSTANCE_ID:執行個體 ID

    HTTP 方法和網址:

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

    JSON 要求主體:

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

    如要傳送要求,請展開以下其中一個選項:

    將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

    curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID"

    將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method PATCH `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID" | Select-Object -Expand Content

    您應該會收到如下的 JSON 回應:

    {
      "kind": "sql#operation",
      "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
      "status": "PENDING",
      "user": "user@example.com",
      "insertTime": "2020-01-20T21:30:35.667Z",
      "operationType": "UPDATE",
      "name": "OPERATION_ID",
      "targetId": "INSTANCE_ID",
      "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
      "targetProject": "PROJECT_ID"
    }
    

伺服器憑證

Cloud SQL 會在您建立執行個體時自動建立伺服器憑證。只要伺服器憑證有效,您就不需要主動管理伺服器憑證。Cloud SQL 提供三種不同的憑證授權單位 (CA) 層級供您選擇。您選取的 CA 層級會成為執行個體的伺服器 CA 模式。如果執行個體使用「每個執行個體 CA」做為伺服器 CA 模式,伺服器憑證的效期為 10 年。如果執行個體的伺服器 CA 模式為共用 CA 或客戶管理的 CA,則伺服器憑證的效期為 1 年*。伺服器憑證過期後即失效,用戶端將無法再使用該憑證與執行個體建立安全連線。如果用戶端設定為驗證 CA 或伺服器憑證中的主機名稱,該用戶端與伺服器憑證過期的 Cloud SQL 執行個體連線時就會失敗。為避免用戶端連線中斷,請在憑證到期前輪替伺服器憑證。系統會定期通知您伺服器憑證即將到期。系統會在到期日前 90 天、30 天、10 天、2 天和 1 天傳送通知。

* 如果您選取的 CA 效期較短,客戶管理的 CA 伺服器憑證到期日可能不到 1 年。

列出及建立伺服器憑證

如要在 Google Cloud 控制台中查看伺服器憑證的詳細資料,請前往「連線」頁面,然後按一下「安全性」分頁標籤。

在認證表格中,您可以看到下列詳細資料:

  • 認證狀態:即將到期、有效或已過期
    • 即將到期:憑證可供使用,但尚未生效。如要啟用憑證,請使用輪替程序。
    • 有效:憑證正在使用中。
    • 先前:憑證已停用。 如要啟用憑證,請使用回溯程序。
  • 建立:憑證的建立日期和時間
  • 到期:憑證到期的日期和時間

您可以在有效憑證到期前,手動建立新憑證。

對於使用自行簽署伺服器憑證的執行個體 (每個執行個體都有 CA)

  1. 前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。

    前往 Cloud SQL 執行個體

  2. 如要開啟執行個體的「總覽」頁面,請按一下執行個體名稱。
  3. 按一下 SQL 導覽選單中的「連線」
  4. 選取「安全性」分頁標籤。
  5. 前往「管理伺服器 CA 憑證」部分。
  6. 按一下即可展開「管理憑證」
  7. 按一下「建立新的 CA 憑證」

新的伺服器 CA 憑證會顯示在「即將到來」時段。如要立即輪替至新的伺服器 CA 憑證,請更新用戶端並完成輪替,以進行伺服器 CA 憑證輪替

對於使用共用 CA 核發伺服器憑證的執行個體

  1. 前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。

    前往 Cloud SQL 執行個體

  2. 如要開啟執行個體的「總覽」頁面,請按一下執行個體名稱。
  3. 按一下 SQL 導覽選單中的「連線」
  4. 選取「安全性」分頁標籤。
  5. 前往「管理伺服器憑證」部分。
  6. 按一下即可展開「管理憑證」
  7. 按一下「建立伺服器憑證」

新的伺服器憑證會顯示在「即將到期」欄位中。如要立即使用新的伺服器憑證,請更新用戶端並完成輪替,以進行伺服器憑證輪替

對於使用自行簽署伺服器憑證的執行個體 (每個執行個體都有 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. 如要取得伺服器憑證的相關資訊,請使用 sql ssl server-certs list 指令:
    gcloud sql ssl server-certs list \
       --instance=INSTANCE_NAME
  2. 如要建立伺服器憑證,請使用 sql ssl server-certs create 指令:
    gcloud sql ssl server-certs create \
       --instance=INSTANCE_NAME
  3. 將憑證資訊下載至本機 PEM 檔案:
    gcloud sql ssl server-certs list \
       --format="value(ca_cert.cert)" \
       --instance=INSTANCE_NAME > \
       FILE_PATH/FILE_NAME.pem
  4. 將下載的檔案複製到用戶端主機,取代現有的 server-ca.pem 檔案,更新所有用戶端以使用新資訊。

如要以輸出內容的形式提供伺服器憑證資訊,請使用 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
       

使用加密連線

進一步瞭解 SQL Server 如何使用加密連線

伺服器身分驗證

伺服器身分驗證取決於 Cloud SQL 執行個體的憑證授權單位 (CA) 階層設定。

如果執行個體使用每個執行個體專屬的 CA,驗證 CA 也會驗證伺服器身分,因為每個執行個體都有專屬的 CA。對於使用共用 CA 的執行個體,由於伺服器 CA 會在執行個體之間共用,因此驗證主機名稱和 CA 是驗證伺服器身分的必要步驟。

如果您有每個執行個體的 CA,則只能針對設定 Private Service Connect 的執行個體,執行以 DNS 名稱為依據的伺服器身分驗證。如果您有共用 CA,則可以對所有類型的執行個體 (即 Private Service Connect私人服務存取權和公用 IP 執行個體) 執行以 DNS 名稱為依據的伺服器身分驗證。

如果您使用客戶管理的 CA,則可驗證 CA 信任鏈結,並針對使用客戶管理 CA 做為 serverCAmode 的任何類型執行個體,執行以 DNS 名稱為基礎的伺服器身分驗證。

為執行個體選取客戶管理的 CA 選項時,您可以在伺服器憑證的 SAN 欄位中插入自訂 DNS 名稱。詳情請參閱「編輯自訂 SAN 欄位」。

如要查看為 Cloud SQL 執行個體設定的 CA 層級,請查看執行個體詳細資料。詳情請參閱「查看執行個體資訊」。

啟用伺服器身分驗證

如果您選取共用 CA 做為 Cloud SQL 執行個體的伺服器 CA 模式,或是使用自訂 SAN 值設定自訂 DNS 名稱,建議您也啟用伺服器身分驗證。

使用共用 CA 做為伺服器 CA 模式的執行個體,會在伺服器憑證的「主體別名」(SAN) 欄位中包含執行個體 DNS 名稱。您可以使用執行個體查詢 API 取得這個 DNS 名稱,並將回應做為伺服器身分驗證的主機名稱。您需要為 DNS 名稱設定 DNS 解析。

如要為使用共用 CA 的執行個體啟用伺服器身分驗證,請完成下列步驟:

  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. 在回應中找出 dnsNames: 欄位。 這個欄位可傳回多個 DNS 名稱,格式如下:

      網路設定 DNS 名稱格式 名稱層級
      Private Service Connect公開 IP 位址 INSTANCE_UID.PROJECT_DNS_LABEL.REGION_NAME.sql.goog.

      示例
      1a23b4cd5e67.1a2b345c6d27.us-central1.sql.goog.
      執行個體
      私人服務存取權 INSTANCE_UID.PROJECT_DNS_LABEL.REGION_NAME.sql-psa.goog.

      示例
      1a23b4cd5e67.1a2b345c6d27.us-central1.sql-psa.goog.
      執行個體
  2. 在 DNS 區域中建立 DNS 記錄。 如果是透過私有連線,請在對應的虛擬私有雲 (VPC) 網路中,於私有 DNS 區域建立 DNS 記錄。

  3. 連線至 Cloud SQL for SQL Server 執行個體時,請將 DNS 名稱或 IP 位址設定為主機名稱。然後為 sqlcmd 指定 -N 旗標,或選取 SSMS 的「加密連線/加密」選項,啟用伺服器身分驗證。

    其他 SQL Server 驅動程式也有類似的旗標或設定。

後續步驟

  • 管理 Cloud SQL 執行個體上的 SSL/TLS 憑證。
  • 進一步瞭解 Google Cloud如何處理加密。