共用方式為


將擁有 TLS 安全性的客戶連接到您的資料庫

概觀

您的客戶端應用程式與資料庫伺服器之間的連線始終使用業界標準的傳輸層安全(TLS),過去稱為安全套接層層(SSL)加密。

備註

開源的 PostgreSQL 在其指令、變數和文件中使用舊名 SSL,以避免破壞現有實作。 本文件使用 TLS 縮寫,但在指令名稱和變數中使用 SSL。

Azure Database for PostgreSQL 支援使用 TLS 1.2 和 1.3 的加密連線。 所有嘗試使用 TLS 1.0 和 TLS 1.1 加密流量的進站連線都會被拒絕。

依預設,會強制執行用戶端與伺服器之間的安全連線。 如果你想關閉 TLS 強制執行,允許加密與未加密的用戶端通訊,你可以將伺服器參數 require_secure_transport 改為 OFF。 您也可以透過設定 ssl_max_protocol_version 伺服器參數來設定 TLS 版本。 我們 強烈建議不要關閉 TLS。

這很重要

我們已開始為 Azure Database for PostgreSQL 進行 TLS 憑證輪替 ,以更新新的中介 CA 憑證及其產生的憑證鏈。 根CA保持不變。

如果您的客戶端設定實作了 TLS 的推薦配置,則無需採取任何行動。

證書輪替時間表

  • Azure 地區(美國中西部、東亞及英國南部)於 2025 年 11 月 11 日開始 TLS 證書輪替。
  • 自 2026 年 1 月 19 日起,此證書輪替計畫將擴展至剩餘(中國除外)區域,包括 Azure 政府。
  • 2026年春節(農曆新年)後,中國各地區也將進行證書輪替,涉及其中一個根 CA 的變更。

用戶端 TLS 設定

根據預設,PostgreSQL 不會執行伺服器憑證的任何驗證。 基於此原因,可能會在用戶端不知情的情況下冒充伺服器身分識別 (例如透過修改 DNS 記錄,或透過接管伺服器 IP 位址)。 為防止此類偽造,必須在用戶端使用 TLS 憑證驗證。

有許多連線參數用於設定 TLS 用戶端。 其中一些重要項目如下:

  • ssl: 使用 TLS 連線。 此屬性不需要與其相關的值。 光是有這個連結就代表有 TLS 連線。 為了確保與未來版本的相容性,建議使用 true 值。 在此模式下,當你建立 TLS 連線時,客戶端驅動程式會驗證伺服器的身份,以防止中間人攻擊。

  • sslmode:如果您需要加密,且想要在無法加密連線時使連線失敗,請設定 sslmode=require。 此設定確保伺服器已設定接受該主機/IP 位址的 TLS 連線,且伺服器能辨識客戶端憑證。 如果伺服器不接受 TLS 連線或客戶端憑證未被辨識,連線就會失敗。 下表列出此設定的值:

    sslmode Explanation
    disable 未使用加密。 Azure Database for PostgreSQL 需要 TLS 連線;因此此設定不得使用。
    allow 如果伺服器設定需要或強制加密,則會使用加密。 Azure Database for PostgreSQL 需要 TLS 連線;因此此設定等價於 prefer
    prefer 如果伺服器設定允許加密,則會使用。 Azure Database for PostgreSQL 需要 TLS 連線。
    require 使用加密。 它確保伺服器已設定為接受 TLS 連線。
    verify-ca 使用加密。 將伺服器憑證與客戶端中儲存的受信任根憑證進行驗證。
    verify-full 使用加密。 請驗證伺服器憑證與客戶端儲存的憑證。 它也會驗證伺服器憑證是否使用與連線相同的主機名稱。 除非私有 DNS 解析器使用不同名稱來參考 PostgreSQL 伺服器的 Azure 資料庫,否則我們建議使用此設定。

使用的預設sslmode模式在基於libpq的客戶端中是不同的(例如PSQLJDBC)。 以 libpq 型用戶端預設為 preferJDBC 用戶端預設為 verify-full

  • sslcertsslkeysslrootcert:這些參數可以覆寫用戶端憑證的預設位置、PKCS-8 用戶端金鑰和根憑證。 它們分別預設為 /defaultdir/postgresql.crt/defaultdir/postgresql.pk8/defaultdir/root.crt,其中在 Linux 系統上為 defaultdir,在 Windows 上為 ${user.home}/.postgresql/

這很重要

某些 Postgres 用戶端程式庫雖然使用 sslmode=verify-full 設定,但可能會因使用中繼憑證交叉簽署的根 CA 憑證而發生連線失敗。 結果是替代信任路徑。 在此情況下,建議您明確指定 sslrootcert 參數。 或者,將 PGSSLROOTCERT 環境變數設定從預設值的 %APPDATA%\postgresql\root.crt 設定為本機路徑,其中放置了 Microsoft RSA Root CA 2017 根 CA 憑證。

安裝受信任的根憑證授權中心(CA)

下載並轉換根 CA 憑證

對於使用 System 憑證儲存庫來管理受信任根憑證的 Windows 用戶端,無需操作,因為 Windows 會透過 Windows Update 部署新的根憑證。

對於 Java 用戶端、VS Code 擴充功能,以及其他不使用系統存放區的用戶端(例如 PSQL、Perl 等),以及 Linux 用戶端:需要下載並將根 CA 憑證合併到 PEM 檔案中。 至少包含以下根憑證憑證:

備註

對於中國地區及擁有輪替延長的客戶: Digicert Global Root CA(pem 檔案) 仍然有效;將其納入合併的 PEM 檔案中。

我們強烈建議包含所有 Azure 根憑證,以減少未來若 Azure 資料庫用於 PostgreSQL 的根憑證有變更時,需更新合併檔案的需求。 Azure 根憑證憑證清單可在 Azure 憑證授權機構詳細資料中找到。

若要將憑證匯入用戶端憑證儲存,您可能需要將任何 CRT 格式憑證轉換為 PEM 格式,並將 PEM 檔案串接成單一檔案。 你可以使用 OpenSSL X509 工具 將 CRT 檔案轉換成 PEM。

openssl x509 -inform DER -in certificate-filename.crt -out certificate-filename.pem -outform PEM

將根憑證合併成單一 PEM 檔案

有些客戶端會用任何文字編輯器或命令列工具將所有 PEM 檔案串接成一個檔案。

-----BEGIN CERTIFICATE-----
(Root CA1 content: DigiCertGlobalRootG2.crt.pem)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root CA2 content: Microsoft ECC Root Certificate Authority 2017.crt.pem)
-----END CERTIFICATE-----

針對中國地區及擁有輪替延長的客戶:

-----BEGIN CERTIFICATE-----
(Root CA0 content: DigiCertGlobalRootCA.crt.pem)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root CA1 content: DigiCertGlobalRootG2.crt.pem)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root CA2 content: Microsoft ECC Root Certificate Authority 2017.crt.pem)
-----END CERTIFICATE-----

為 Java 應用程式組合並更新根 CA 憑證

自訂撰寫的 Java 應用程式會使用預設金鑰存放區 (稱為 cacerts),其中包含信任的憑證授權單位 (CA) 憑證。 名為 cacerts 的憑證檔案位於安全性屬性目錄 (java.home\lib\security),其中 java.home 是執行階段環境目錄 (SDK 中的 jre 目錄或 Java™ 2 Runtime Environment 的最上層目)。 您可以依照以下指示來更新用於 PostgreSQL 客戶端憑證釘選場景的客戶端根 CA 憑證:

  1. 檢查 cacerts Java 金鑰存放區,查看它是否已經包含必要的憑證。 您可使用下列命令,在 Java 金鑰存放區中列出憑證:

    keytool -list -v -keystore ..\lib\security\cacerts > outputfile.txt
    

    如果用戶端上的 java 金鑰存放區中沒有必要的憑證 (可在輸出中檢查),您應該繼續下列指示:

  2. 製作自訂金鑰存放區的備份複本。

  3. 下載憑證檔案,並存到本地以便查閱。

  4. 產生包含所有必要根 CA 憑證的合併 CA 憑證存放區。 以下範例展示了 PostgreSQL Java 使用者使用 DefaultJavaSSLFactory 的範例。

    keytool -importcert -alias PostgreSQLServerCACert  -file "DigiCertGlobalRootG2.crt.pem" -keystore truststore -storepass password -noprompt
    
    keytool -importcert -alias PostgreSQLServerCACert2  -file "Microsoft ECC Root Certificate Authority 2017.crt.pem" -keystore truststore -storepass password  -noprompt
    
    ...
    

更新 Azure App Services 中的根 CA 憑證

針對 Azure App Services,當連線到適用於 PostgreSQL 的 Azure 資料庫彈性伺服器執行個體時,我們在更新用戶端憑證時可能會遇到兩種情況,這取決於您如何將 SSL 與部署至 Azure App Services 的應用程式搭配使用。

  • 在適用於 PostgreSQL 的 Azure 資料庫彈性伺服器執行個體發生變更之前,新的憑證會在平臺層級新增至 App Service。 如果您要在應用程式中使用 App Service 平台上所含的 SSL 憑證,則無需採取任何動作。 如需詳細資訊,請參閱 Azure App Service 文件中的在 Azure App Service 中新增和管理 TLS/SSL 憑證
  • 如果您在程式碼中明確包含 SSL 憑證檔案的路徑,則必須下載新的憑證,並更新程式碼才能使用它。

在 Azure Kubernetes Service(AKS)中使用客戶端時,更新 Root CA 憑證

如果你想透過 Azure Kubernetes Services(AKS)中託管的應用程式連接到 PostgreSQL 的 Azure 資料庫,這類似於從專用客戶的主機環境存取。 詳見 AKS文件中的詳細說明

在 Windows 上更新 .NET (Npgsql) 使用者的 Root CA 憑證

對於 Windows 上的 .NET (Npgsql) 使用者,在連接到 Azure Database for PostgreSQL 彈性伺服器實例時,請確保 所有 根憑證都已包含在 Windows 憑證儲存庫中的受信任根憑證機構。 Windows Update 維護標準的 Azure 根 CA 清單。 如果我們 推薦設定 中沒有列出任何憑證,請匯入缺少的憑證。

如何使用 TLS 進行憑證驗證

某些將 PostgreSQL 用於其資料庫服務的應用程式架構在安裝期間預設不會啟用 TLS。 你的 Azure 資料庫用於 PostgreSQL 實例會強制執行 TLS 連線,但如果應用程式沒有設定 TLS,應用程式可能會失敗。 請參閱您的應用程式文件,以了解如何啟用 TLS 連線。

使用 PSQL 進行連接

以下範例展示了如何使用 PSQL 命令列介面連接你的伺服器。 使用 sslmode=verify-full or sslmode=verify-ca 連線字串設定來強制執行 TLS 憑證驗證。 將本機憑證檔案路徑傳遞至 sslrootcert 參數。

 psql "sslmode=verify-full sslrootcert=<path-of-pem-file> host=mydemoserver.postgres.database.azure.com dbname=postgres user=myadmin"

測試 TLS 連線

在你嘗試從客戶端應用程式存取支援 TLS 的伺服器之前,請確保你能透過 PSQL。 如果你建立了 TLS 連線,應該會看到類似以下範例的輸出:

psql (14.5)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

你也可以載入 sslinfo 擴充功能 ,然後呼叫該 ssl_is_used() 函式來判斷是否使用 TLS。 如果連線使用 TLS,函式會回傳 t 。 否則會傳回 f

以程式設計方式取得 Java 金鑰存放區中受信任的憑證清單

依預設,Java 會將受信任的憑證儲存在名為 cacerts 的特殊檔案中,該檔案位於用戶端上的 Java 安裝資料夾內。 下面的範例會先讀取 cacerts 並將其載入到 KeyStore 物件中:

private KeyStore loadKeyStore() {
    String relativeCacertsPath = "/lib/security/cacerts".replace("/", File.separator);
    String filename = System.getProperty("java.home") + relativeCacertsPath;
    FileInputStream is = new FileInputStream(filename);
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    String password = "changeit";
    keystore.load(is, password.toCharArray());

    return keystore;
}

cacerts 的預設密碼為 changeit,但在實際用戶端上應該有所不同,因為系統管理員建議在安裝 Java 後立即變更密碼。 載入 KeyStore 物件後,我們可以使用 PKIXParameters 類別來讀取存在的憑證。

public void whenLoadingCacertsKeyStore_thenCertificatesArePresent() {
    KeyStore keyStore = loadKeyStore();
    PKIXParameters params = new PKIXParameters(keyStore);
    Set<TrustAnchor> trustAnchors = params.getTrustAnchors();
    List<Certificate> certificates = trustAnchors.stream()
      .map(TrustAnchor::getTrustedCert)
      .collect(Collectors.toList());

    assertFalse(certificates.isEmpty());
}