支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

18.9. 使用 SSL 保護 TCP/IP 連線 #

PostgreSQL 具有原生支援,可使用SSL連線來加密用戶端/伺服器通訊,以提高安全性。這需要用戶端和伺服器系統上都已安裝 OpenSSL,並且在建置時已啟用 PostgreSQL 中的支援 (請參閱第 17 章)。

術語SSLTLS經常互換使用,表示使用一種TLS協定的安全加密連線。SSL協定是TLS協定的前身,即使不再支援SSL協定,仍然使用SSL一詞來表示加密連線。SSLPostgreSQL 中與TLS可互換使用。

18.9.1. 基本設定 #

在編譯時包含SSL支援的情況下,可以啟動 PostgreSQL 伺服器,並透過在 postgresql.conf 中將參數 ssl 設定為 on 來啟用對使用TLS協定的加密連線的支援。伺服器將在同一個 TCP 埠上偵聽一般連線和SSL連線,並與任何連線的用戶端協商是否使用SSL。預設情況下,這由用戶端決定;請參閱第 20.1 節,瞭解如何設定伺服器以要求對某些或所有連線使用SSL

若要在SSL模式下啟動,必須存在包含伺服器憑證和私密金鑰的檔案。預設情況下,這些檔案預期分別命名為 server.crtserver.key,位於伺服器的資料目錄中,但可以使用組態參數 ssl_cert_filessl_key_file 指定其他名稱和位置。

在 Unix 系統上,server.key 的權限必須不允許任何對世界或群組的存取;透過命令 chmod 0600 server.key 達成此目的。或者,該檔案可以由 root 擁有,並具有群組讀取權限 (即 0640 權限)。該設定適用於憑證和金鑰檔案由作業系統管理的安裝。然後,應該讓執行 PostgreSQL 伺服器的使用者成為可以存取這些憑證和金鑰檔案的群組的成員。

如果資料目錄允許群組讀取存取權限,則可能需要將憑證檔案放置在資料目錄之外,以符合上述安全需求。通常,啟用群組存取權限是為了允許非特權使用者備份資料庫,在這種情況下,備份軟體將無法讀取憑證檔案,並且很可能會發生錯誤。

如果私密金鑰受到密碼保護,伺服器將提示輸入密碼,並且在輸入密碼之前不會啟動。預設情況下,使用密碼會停用在不重新啟動伺服器的情況下變更伺服器的 SSL 組態的功能,但請參閱 ssl_passphrase_command_supports_reload。此外,在 Windows 上根本無法使用受密碼保護的私密金鑰。

server.crt 中的第一個憑證必須是伺服器的憑證,因為它必須與伺服器的私密金鑰相符。也可以將中間憑證授權單位的憑證附加到檔案中。假設根憑證和中間憑證是使用 v3_ca 擴充功能建立的,這樣做可以避免在用戶端上儲存中間憑證的必要性。(這會將憑證的基本限制 CA 設定為 true。) 這可以更容易地使中間憑證過期。

不需要將根憑證新增到 server.crt。相反地,用戶端必須擁有伺服器憑證鏈的根憑證。

18.9.2. OpenSSL 設定 #

PostgreSQL 會讀取系統範圍的 OpenSSL 組態檔案。預設情況下,此檔案名為 openssl.cnf,位於 openssl version -d 報告的目錄中。可以透過將環境變數 OPENSSL_CONF 設定為所需的組態檔案名稱來覆寫此預設值。

OpenSSL 支援多種強度不同的加密演算法與認證演算法。雖然可以在 OpenSSL 設定檔中指定加密演算法列表,但您可以透過修改 postgresql.conf 中的 ssl_ciphers,來指定資料庫伺服器專用的加密演算法。

注意

可以使用 NULL-SHANULL-MD5 加密演算法來進行身份驗證,而沒有加密的額外負擔。然而,中間人可以讀取和傳遞客戶端和伺服器之間的通訊。此外,與身份驗證的負擔相比,加密的負擔非常小。由於這些原因,不建議使用 NULL 加密演算法。

18.9.3. 使用客戶端憑證 #

要要求客戶端提供受信任的憑證,請將您信任的根憑證授權單位(CA)的憑證放置在資料目錄中的一個檔案中,將 postgresql.conf 中的參數 ssl_ca_file 設定為新的檔案名稱,並將身份驗證選項 clientcert=verify-caclientcert=verify-full 新增到 pg_hba.conf 中適當的 hostssl 行。然後,在 SSL 連線啟動期間,將會向客戶端請求憑證。(有關如何在客戶端上設定憑證的說明,請參閱第 32.19 節。)

對於具有 clientcert=verify-cahostssl 項目,伺服器將驗證客戶端的憑證是否由受信任的憑證授權單位簽署。如果指定了 clientcert=verify-full,伺服器不僅會驗證憑證鏈,還會檢查使用者名稱或其對應是否與提供的憑證的 cn(Common Name)相符。請注意,當使用 cert 身份驗證方法時,始終會確保憑證鏈驗證(請參閱第 20.12 節)。

如果您希望避免將中間憑證儲存在客戶端上(假設根憑證和中間憑證是使用 v3_ca 擴充功能建立的),則鏈接到現有根憑證的中間憑證也可以出現在 ssl_ca_file 檔案中。如果設定了參數 ssl_crl_filessl_crl_dir,也會檢查憑證撤銷清單 (CRL) 項目。

The clientcert 身份驗證選項適用於所有身份驗證方法,但僅適用於指定為 hostsslpg_hba.conf 行。當未指定 clientcert 時,只有在提供客戶端憑證且已設定 CA 時,伺服器才會針對其 CA 檔案驗證客戶端憑證。

有兩種方法可以強制使用者在登入期間提供憑證。

第一種方法是將 cert 身份驗證方法用於 pg_hba.conf 中的 hostssl 項目,這樣憑證本身可用於身份驗證,同時還提供 SSL 連線安全性。有關詳細訊息,請參閱第 20.12 節。(使用 cert 身份驗證方法時,無需明確指定任何 clientcert 選項。)在這種情況下,會針對使用者名稱或適用的對應檢查憑證中提供的 cn(Common Name)。

第二種方法是將 hostssl 項目的任何身份驗證方法與驗證客戶端憑證相結合,方法是將 clientcert 身份驗證選項設定為 verify-caverify-full。 前者選項僅強制憑證有效,而後者選項還確保憑證中的 cn(Common Name)與使用者名稱或適用的對應相符。

18.9.4. SSL 伺服器檔案使用方式 #

表 18.2 總結了與伺服器上 SSL 設定相關的檔案。(顯示的檔案名稱是預設名稱。本地設定的名稱可能不同。)

表 18.2. SSL 伺服器檔案使用方式

檔案 內容 效果
ssl_cert_file ($PGDATA/server.crt) 伺服器憑證 傳送給客戶端以指示伺服器的身份
ssl_key_file ($PGDATA/server.key) 伺服器私鑰 證明伺服器憑證是由所有者傳送的;不表示憑證所有者是值得信賴的
ssl_ca_file 受信任的憑證授權單位 檢查客戶端憑證是否由受信任的憑證授權單位簽署
ssl_crl_file 由憑證授權單位撤銷的憑證 客戶端憑證不得在此清單上

伺服器會在伺服器啟動時以及每次重新載入伺服器設定時讀取這些檔案。 在 Windows 系統上,每當為新的客戶端連線產生新的後端程序時,也會重新讀取這些檔案。

如果在伺服器啟動時偵測到這些檔案中的錯誤,伺服器將拒絕啟動。 但是,如果在設定重新載入期間偵測到錯誤,則會忽略這些檔案,並繼續使用舊的 SSL 設定。 在 Windows 系統上,如果在後端啟動時偵測到這些檔案中的錯誤,則該後端將無法建立 SSL 連線。 在所有這些情況下,錯誤情況都會報告在伺服器日誌中。

18.9.5. 建立憑證 #

若要為伺服器建立一個簡單的自簽憑證,有效期為 365 天,請使用以下 OpenSSL 命令,將 dbhost.yourdomain.com 替換為伺服器的主機名稱

openssl req -new -x509 -days 365 -nodes -text -out server.crt \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"

然後執行

chmod og-rwx server.key

因為如果檔案的權限比這更寬鬆,伺服器將拒絕該檔案。 有關如何建立伺服器私鑰和憑證的更多詳細訊息,請參閱 OpenSSL 文件。

雖然自簽憑證可以用於測試,但憑證授權單位簽署的憑證(CA) (通常是企業範圍的根CA)應該在生產環境中使用。

若要建立一個客戶端可以驗證其身份的伺服器憑證,首先建立一個憑證簽署請求(CSR)和一個公鑰/私鑰檔案

openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key

然後,使用金鑰簽署請求以建立根憑證授權單位(使用 Linux 上的預設 OpenSSL 設定檔位置)

openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

最後,建立一個由新的根憑證授權單位簽署的伺服器憑證

openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key

openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt

server.crtserver.key 應儲存在伺服器上,而 root.crt 應儲存在客戶端上,以便客戶端可以驗證伺服器的葉憑證是否由其受信任的根憑證簽署。 root.key 應離線儲存,以用於建立未來的憑證。

也可以建立包含中間憑證的信任鏈

# root
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

# intermediate
openssl req -new -nodes -text -out intermediate.csr \
  -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com"
chmod og-rwx intermediate.key
openssl x509 -req -in intermediate.csr -text -days 1825 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out intermediate.crt

# leaf
openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
  -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
  -out server.crt

server.crtintermediate.crt 應被串連成一個憑證檔案包,並儲存在伺服器上。server.key 也應儲存在伺服器上。root.crt 應儲存在用戶端,以便用戶端驗證伺服器的葉憑證是否由連結到其信任根憑證的憑證鏈簽署。root.keyintermediate.key 應離線儲存,以供日後建立憑證時使用。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表單回報文件問題。