PostgreSQL10.1手冊_部分IV.客戶端介面_第33章libpq-C庫_33.18.SSL支援
33.18. SSL 支援
PostgreSQL本地支援使用SSL 連線加密客戶端/伺服器通訊以提高安全性。關於伺服器端的SSL 功能詳見第 18.9 節。
libpq讀取系統範圍的OpenSSL 配置檔案。預設情況下,這個檔案被命名為openssl.cnf
並且存放在 openssl version -d
報告的目錄中。可以通過設定環境變數 OPENSSL_CONF
把這個預設值覆蓋為想要的配置檔案的名稱。
33.18.1. 伺服器證書的客戶端驗證
預設情況下,PostgreSQL將不會執行伺服器證書的任何驗證。 這意味著可以在不被客戶端知曉的情況下偽造伺服器身份 (例如通過修改一個 DNS 記錄或者接管伺服器的 IP 地址)。為了阻止哄騙, 必須使用SSL證書驗證。
如果引數sslmode
被設定為verify-ca
, libpq 將通過檢查證書鏈一直到一個可信的證書機構(CA) 來驗證伺服器是可信的。如果sslmode
被設定為verify-full
, libpq 將還會驗證伺服器主機名是否匹配它的證書。 如果伺服器證書不能被驗證,SSL 連線將失敗。在大部分對安全敏感的環境中, 建議使用verify-full
。
在verify-full
模式下,主機名與證書的Subject Alternative Name (主題備用名稱)屬性進行匹配, 或者如果沒有型別為dNSName的主題備用名稱,則與Common Name(公用名稱)屬性進行匹配。 如果證書的名稱屬性以星號( *
)開頭,則星號將被視為萬用字元, 其將匹配除了點(.
)之外的所有字元。這意味著證書將不會匹配子域。 如果使用IP地址而不是主機名進行連線,則將匹配IP地址(不進行任何DNS查詢)。
要允許伺服器證書驗證,一個或多個可信的CA必須被放置在使用者home目錄下的檔案 ~/.postgresql/root.crt
中。如果中間CA出現在 root.crt
中,該檔案必須也包含到它們的根CA的證書鏈 (在微軟 Windows 上該檔案被命名為%APPDATA%postgresql
)。
oot.crt
如果檔案~/.postgresql/root.crl
存在 (微軟 Windows 上的%APPDATA%postgresql
), 也會檢查證書撤銷列表(CRL)項。
oot.crl
根證書檔案和 CRL 的位置可以通過設定連線引數sslrootcert
和 sslcrl
或環境變數PGSSLROOTCERT
和PGSSLCRL
改變。
注意
為了與 PostgreSQL 的早期版本達到向後相容,如果存在一個根 CA 檔案,sslmode
=require
的行為將與 verify-ca
相同,意味著伺服器證書根據 CA 驗證。 不鼓勵依賴這種行為,並且需要證書驗證的應用程式應該總是使用 verify-ca
或者verify-full
。
33.18.2. 客戶端證書
如果伺服器要求一個可信的客戶端證書,libpq 將傳送使用者主目錄中~/.postgresql/postgresql.crt
檔案儲存的證書。 該證書必須由一個受伺服器信任的證書機構(CA)簽發。 也必須存在一個匹配的私鑰檔案~/.postgresql/postgresql.key
。 該私鑰檔案不允許全域性或組使用者的任何訪問,可以通過命令 chmod 0600 ~/.postgresql/postgresql.key
實現。 在微軟 Windows 上這些檔案被命名為%APPDATA%postgresqlpostgresql.crt
和%APPDATA%postgresqlpostgresql.key
,不會有特別的許可權檢查, 因為該目錄被假定為安全。證書和金鑰檔案的位置可以使用連線引數sslcert
和sslkey
或者環境變數PGSSLCERT
和PGSSLKEY
覆蓋。
在一些情況下,客戶端證書可以由“中間”證書機構簽名, 而不是由伺服器直接信任的證書機構。 要使用這樣一個證書,將簽發機構的證書加入到postgresql.crt
檔案, 然後是它的上級機構的證書,並且一直到一個受伺服器信任的證書機構( “根”機構或者“中間”機構),即由該伺服器的 root.crt
檔案中的一個證書籤發。
注意客戶端的~/.postgresql/root.crt
列出了被認為可信的能用於簽發伺服器證書的頂層 CA。 原則上不需要列出簽發客戶端證書的 CA, 大部分情況下這些 CA 也被信任可以用於伺服器證書。
33.18.3. 不同模式中提供的保護
sslmode
引數的不同值提供了不同級別的保護。 SSL 能夠針對三類攻擊提供保護:
- 竊聽
-
如果一個第三方能夠檢查客戶端和伺服器之間的網路流量, 它能讀取連線資訊(包括使用者名稱和口令)以及被傳遞的資料。 SSL使用加密來阻止這種攻擊。
- 中間人(MITM)
-
如果一個第三方能對客戶端和伺服器之間傳送的資料進行修改, 它就能假裝是伺服器並且因此能看見並且修改資料,即使這些資料已被加密。 然後第三方可以將連線資訊和資料傳送給原來的伺服器,使得它不可能檢測到攻擊。 這樣做的常用載體包括 DNS 中毒和地址劫持,藉此客戶端被定向到預期之外的不同的伺服器。 還有幾種其他的攻擊方式能夠完成這種攻擊。SSL 使用證書驗證讓客戶端認證伺服器,就可以阻止這種攻擊。
- 模仿
-
如果第三方可以偽裝成一個授權的客戶端, 那麼它能夠輕鬆訪問它本不能訪問的資料。通常這可以由不安全的口令管理所致。 SSL使用客戶端證書來阻止這種情況, 即確保只有持有合法證書的客戶才能訪問伺服器。
對於一個已知安全的連線,在連線被建立之前,必須在 客戶端和伺服器端都進行SSL配置。如果只在伺服器上配置, 客戶端在知道伺服器要求高安全性之前可能會結束髮送敏感資訊(例如口令)。 在 libpq 中,可以通過將sslmode
引數設定為verify-full
或 verify-ca
來確保安全連線,並且為系統提供一個根證書用來驗證。 這類似於使用https
URL進行加密網頁瀏覽。
一旦伺服器已經被認證,客戶端可以傳遞敏感資料。這意味著直到這一點, 客戶端都不需要知道是否證書將被用於認證,這樣只需要在伺服器配置中指定就比較安全。
所有SSL選項都帶來了加密和金鑰交換的開銷, 因此必須在效能和安全性之間做出平衡。表 33.1 說明不同sslmode
值所保護的風險,以及關於安全和開銷所做出的宣告。
表 33.1. SSL 模式描述
sslmode |
竊聽保護 | MITM保護 | 宣告 |
---|---|---|---|
disable |
否 | 否 | 我不關心安全性,並且我不想承擔加密的開銷。 |
allow |
可能 | 否 | 我不關心安全性,但如果伺服器堅持,我會承擔加密開銷 。 |
prefer |
可能 | 否 | 我不關心加密,但如果伺服器支援,我希望承擔加密開銷。 |
require |
是 | 否 | 我希望我的資料加密,我接受開銷。 我相信該網路將確保我始終連線到想要連線的伺服器。 |
verify-ca |
是 |
取決於 CA -策略 |
我希望我的資料加密,我接受開銷。 我想要確保我連線到的是我信任的伺服器。 |
verify-full |
是 | 是 | 我希望我的資料加密,我接受開銷。 我想要確保我連線到的是我信任的伺服器,並且就是我指定的那一個。 |
verify-ca
和verify-full
之間的區別取決於根CA的策略。 如果使用了一個公共CA,verify-ca
允許連線到那些可能已經被 其他人註冊到該CA的伺服器。在這種情況下,總是應該使用verify-full
。如果使用了一個本地CA或者甚至是一個自簽名的證書, 使用verify-ca
通常就可以提供足夠的保護。
sslmode
的預設值是prefer
。如表中所示, 從安全形度來看這樣做是沒有意義的,並且它只承諾可能的效能開銷。 提供它作為預設值只是為了向後相容,在安全部署中不建議使用。
33.18.4. SSL 客戶端檔案使用
表 33.2總結了與客戶端 SSL 設定相關的檔案。
表 33.2. Libpq/客戶端 SSL 檔案用法
檔案 | 內容 | 影響 |
---|---|---|
~/.postgresql/postgresql.crt |
客戶端證書 | 由伺服器要求 |
~/.postgresql/postgresql.key |
客戶端私鑰 | 證明由所有者傳送客戶端證書,並不表示證書所有者是可信的 |
~/.postgresql/root.crt |
受信任的證書頒發機構 | 檢查伺服器證書是由一個可信的證書機構簽發 |
~/.postgresql/root.crl |
被證書頒發機構撤銷的證書 | 伺服器證書必須不在這個列表中 |
33.18.5. SSL 庫初始化
如果你的應用初始化libssl
或libcrypto
庫以及 libpq編譯為支援SSL,你應該呼叫 PQinitOpenSSL
來告訴libpq:libssl
或libcrypto
庫已經被你的應用初始化,這樣libpq 將不會再初始化這些庫。 關於 SSL API 詳見http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04.html。
PQinitOpenSSL
-
允許應用選擇要初始化哪個安全庫。
void PQinitOpenSSL(int do_ssl, int do_crypto);
當
do_ssl
是非零時,libpq 將在第一次開啟資料庫連線前初始化OpenSSL庫。 當do_crypto
是非零時,libcrypto
庫將被初始化。 預設情況下(如果沒有呼叫PQinitOpenSSL
),兩個庫都會被初始化。 當 SSL 支援沒有被編譯時,這個函式也存在但是什麼也不做。如果你的應用使用並且初始化OpenSSL或者它的底層
libcrypto
庫, 你必須在第一次開啟資料庫連線前以合適的非零引數呼叫這個函式。 同時要確保在開啟一個資料庫連線前已經完成了初始化。 PQinitSSL
-
允許應用選擇要初始化哪個安全庫。
void PQinitSSL(int do_ssl);
這個函式等效於
PQinitOpenSSL(do_ssl, do_ssl)
。 這對於要麼初始化OpenSSL以及libcrypto
要麼都不初始化的應用足夠用了。PQinitSSL
從PostgreSQL 8.0 就存在了, 而PQinitOpenSSL
直到PostgreSQL 8.4 才被加入, 因此PQinitSSL
可能對那些需要與舊版本 libpq一起工作的應用來說更合適。 -
本文轉自PostgreSQL中文社群,原文連結:33.18. SSL 支援
相關文章
- PostgreSQL10.1手冊_部分IV.客戶端介面_第33章libpq-C庫_33.19.線上程化程式中的行為SQL客戶端
- PostgreSQL10.1手冊_部分III.伺服器管理_第22章管理資料庫_22.6.表空間SQL伺服器資料庫
- Nacos - 客戶端註冊客戶端
- PostgreSQL10.1手冊_部分III.伺服器管理_第31章邏輯複製_31.7.安全SQL伺服器
- PostgreSQL10.1手冊_部分II.SQL語言_第8章資料型別_8.12.UUID型別SQL資料型別UI
- PostgreSQL10.1手冊_部分II.SQL語言_第15章並行查詢_15.4.並行安全性SQL並行
- PostgreSQL10.1手冊_部分III.伺服器管理_第18章伺服器設定和操作_18.4.管理核心資源SQL伺服器
- validation客戶端驗證框架使用手冊客戶端框架
- CouchBase C 客戶端介面呼叫例項客戶端
- 羽毛球群檔案--客戶手冊
- Zookeeper C客戶端庫編譯客戶端編譯
- Kubernetes客戶端和管理介面大集合客戶端
- 自己動手寫個 Android客戶端Android客戶端
- 如果呼叫遠端遠端url介面為https,且存在客戶端證書驗證,如何在客戶端處理HTTP客戶端
- PySimpleGUI 中文手冊(常用部分)GUI
- 在 WPF 客戶端實現 AOP 和介面快取客戶端快取
- dubbo客戶端客戶端
- Pulsar客戶端客戶端
- mqtt 客戶端MQQT客戶端
- 精講RestTemplate第2篇-多種底層HTTP客戶端類庫的切換RESTHTTP客戶端
- 服務端,客戶端服務端客戶端
- 客戶端,服務端客戶端服務端
- Nacos - 客戶端心跳續約及客戶端總結客戶端
- 一個支援Sora模型文字生成影片的Web客戶端Sora模型Web客戶端
- moose 免費版- 支援即時播放B/T客戶端客戶端
- 油管去廣告客戶端:Clicker for mac(支援m1)客戶端Mac
- 使用 Golang 實現 appium/WebDriverAgent 的客戶端庫GolangAPPWeb客戶端
- SQLPro Studio Mac資料庫管理客戶端工具SQLMac資料庫客戶端
- 強大的Git客戶端:Tower for Mac註冊啟用版Git客戶端Mac
- 物理DataGuard客戶端無縫切換--客戶端TAF 配置客戶端
- [Redis 客戶端整合] Java 中常用Redis客戶端比較Redis客戶端Java
- 開源文件工具 showdoc 推出除錯介面的客戶端除錯客戶端
- 強大的Git客戶端:Tower for Mac註冊啟用版 附 啟用金鑰 支援M1Git客戶端Mac
- 服務端和客戶端 RESTful 介面上傳 Excel 的 Python 程式碼服務端客戶端RESTExcelPython
- 利用tirpc庫實現簡單的客戶端和服務端RPC客戶端服務端
- java websocket 客戶端JavaWeb客戶端
- redis客戶端管理Redis客戶端
- iscsi linux客戶端Linux客戶端