上一篇文章《openGauss與PostgreSQL對比測試SSL之自簽名私有證書測試》測試了自簽名私有證書,只用于測試傳輸加密,不具備身份驗證功能。
本文測試自簽名CA證書的單向認證: 客戶端只驗證服務器證書的有效性,而服務器端不驗證客戶端證書的有效性。服務器加載證書信息并發送給客戶端,客戶端使用根證書來驗證服務器端證書的有效性。
服務端證書的客戶端認證模式
客戶端SSLMODE設置為verify-ca僅校驗數據庫證書真偽
客戶端SSLMODE設置為verify-full校驗數據庫證書真偽及
通用名CN匹配數據庫連接的hostname
自簽名CA證書單向認證測試
1.創建CA證書
CA證書用于給數據庫服務器證書簽名,同時需要把CA證書發送給數據庫客戶端,客戶端使用CA證書驗證數據庫服務器證書。
$ openssl req -new -x509 -days 365 -nodes \
-config openssl.cnf \
-out ca.crt -keyout ca.key -subj "/CN=FooCA"
2.生成數據庫服務器證書請求文件
$ openssl req -new -nodes -text \
-config openssl.cnf \
-out server.csr \
-keyout server.key \
-subj "/CN=192.168.137.5"
將證書請求文件(包含用戶信息)和證書簽名分開操作,證書請求文件可重用,因為后面可能需要重新生成簽名信息。
3.使用CA證書對證書請求文件簽名
$ openssl x509 -req -in server.csr -text -days 5 \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt
這里設置有效期為5天,可以觀察在服務器證書有效期小于7天的時候,連接登錄后會在日志中產生告警提醒。
4.傳輸數據庫服務器證書及未加密的私鑰文件至數據庫服務器
修改文件權限以符合安全設置
$ chmod 0600 server.crt server.key
傳輸文件到數據庫服務器PGDATA目錄
$ cp server.crt server.key $PGDATA
注意:如果PostgreSQL使用-g, --allow-group-access
開啟了組訪問權限,則需要拷貝文件到PGDATA目錄之外以符合安全設置。
5.數據庫SSL參數配置
pg_hba.conf文件配置hostssl條目,認證方法保持md5或者scram不變。
hostssl all all 0.0.0.0/0 md5
說明:也可以按原來的host連接類型,同時支持非ssl和ssl連接,配置為hostssl只支持hostssl,這里配置為hostssl。
postgreql.conf文件配置參數
ssl=on
ssl_cert_file= 'server.crt'
ssl_key_file= 'server.key'
然后重啟數據庫服務。
6.發送CA證書到數據庫客戶端
本文數據庫客戶端使用linux下psql,證書文件的默認路徑為$HOME/.postgresql/root.crt。
cat ca.crt > ~/.postgresql/root.crt
chmod 0600 ~/.postgresql/root.crt
測試一
數據庫客戶端未配置證書測試,刪除上面第6步的文件
gsql "sslmode=verify-ca" -p6432 -h 192.168.137.5 -Upostgres
gsql: root certificate file "/home/omm/.postgresql/root.crt" does not exist
Either provide the file or change sslmode to disable server certificate verification.
PostgreSQL
psql "sslmode=verify-ca" -h192.168.137.11
psql: error: root certificate file "/home/postgres/.postgresql/root.crt" does not exist
Either provide the file or change sslmode to disable server certificate verification.
可以看到設置sslmode=verify-ca后,客戶端需要驗證服務器證書,未配置默認root.crt問題,提示文件不存在,符合預期。
測試二
人為修改數據庫客戶端證書內容
gsql "sslmode=verify-ca" -p6432 -h 192.168.137.5 -Upostgres
gsql: could not read root certificate file "/home/omm/.postgresql/root.crt": too long
gsql "sslmode=verify-ca" -p6432 -h 192.168.137.5 -Upostgres
gsql: could not read root certificate file "/home/omm/.postgresql/root.crt": wrong tag
PostgreSQL
psql "sslmode=verify-ca" -h192.168.137.11
psql: error: could not read root certificate file "/home/postgres/.postgresql/root.crt":
bad base64 decode
psql "sslmode=verify-ca" -p7000 -h192.168.137.11
psql: error: could not read root certificate file "/home/postgres/.postgresql/root.crt": too long
可以看到root.crt證書文件內容如果被篡改也是有相應的報錯提示,符合預期。
測試三
測試驗證數據庫服務器證書,將正確的證書文件發送至數據庫客戶端,參考上面第6步配置
gsql "sslmode=verify-ca" -p6432 -h 192.168.137.5 -Upostgres
Password for user postgres:
gsql ((GaussDB Kernel V500R001C20 build ) compiled at 2021-03-09 18:30:51 commit 0 last mr )
SSL connection (cipher: DHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
postgres=>
PostgreSQL
psql "sslmode=verify-ca" -h192.168.137.11
Password for user postgres:
psql (12.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=# \q
使用sslmode=verify-ca僅驗證服務器證書真偽,符合預期。
測試四
測試數據庫服務器證書設置的通用名CN是否匹配客戶端連接的hostname
gsql "sslmode=verify-full" -p6432 -h nodex -Upostgres
gsql: server common name "192.168.137.5" does not match host name "nodex"
PostgreSQL
psql "sslmode=verify-full" -hnode11
psql: error: server certificate for "192.168.137.11" does not match host name "node11"
分別使用ip地址及主機名測試,與通用名CN匹配的ip地址可成功登錄,使用主機名連接報錯,報錯提示如上,符合預期。
總結
1.數據庫服務器證書的客戶端認證需要在客戶端配置服務器證書簽名的CA證書,服務器設置支持hostssl連接,客戶端使用sslmode連接參數。
2.sslmode連接參數設置為verify-ca僅校驗數據庫證書真偽,設置為verify-full校驗數據庫證書真偽及通用名CN匹配數據庫連接的hostname。




