暂无图片
暂无图片
8
暂无图片
暂无图片
暂无图片

PG数据库中SSL那些事

原创 严少安 2024-08-12
926

PG数据库中SSL那些事

在当今这个数据安全至关重要的时代,数据库的加密连接已成为保护数据传输安全的常规手段。PostgreSQL数据库作为一个功能强大的开源数据库系统,提供了SSL(Secure Sockets Layer)支持来确保数据在客户端和服务器之间的安全传输。本文将探讨PostgreSQL中SSL的使用和配置,以及如何通过SSL加强数据库的安全性。

配置PG以使用SSL

首先,要在PostgreSQL中启用SSL,需要在编译安装阶段通过特定的配置选项来指定。

./configure --with-openssl

从 PG 14 开始,引入新选项--with-ssl=LIBRARY来指定SSL类库,不过到目前为止仍然只支持 OpenSSL,所以习惯上依旧使用 --with-openssl 兼容选项。

如果编译阶段未指定SSL,后期在开启时会遇到报错。

[postgres@pg16 ~]$ psql
psql (16.4-ShawnYan)
Type "help" for help.

postgres=# alter system set ssl = on ;
ERROR:  SSL is not supported by this build

生成SSL证书和密钥

在启用SSL之前,需要生成SSL证书和私钥。通过openssl命令行工具,我们可以创建自签名的根证书和服务器证书。可以通过如下命令生成服务器证书postgresql.crt和私钥postgresql.key,以及根证书root.crt和相应的私钥root.key。生成这些文件后,需要确保私钥文件的权限设置正确,以防止未授权访问。

openssl req -new -x509 -days 365 -nodes -text -out postgresql.crt \
  -keyout postgresql.key -subj "/CN=pg16.shawnyan.cn"
chmod og-rwx postgresql.key
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=pg16.shawnyan.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
  -signkey root.key -out root.crt
openssl req -new -nodes -text -out postgresql.csr \
  -keyout postgresql.key -subj "/CN=pg16.shawnyan.com"
chmod og-rwx postgresql.key
openssl x509 -req -in postgresql.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out postgresql.crt

修改配置文件

生成SSL证书和密钥后,需要在PostgreSQL的配置文件中指定这些文件的位置。修改postgresql.conf文件,设置ssl_cert_filessl_key_file参数指向相应的证书和密钥文件。

[postgres@pg16 data]$ grep '^ssl' postgresql.conf 
ssl = on
ssl_cert_file = 'postgresql.crt'
ssl_key_file = 'postgresql.key'

连接数据库时使用SSL

在客户端连接数据库时,可以通过指定连接字符串中的sslmode参数来要求SSL连接。

如下,使用psql命令行工具连接数据库时,通过sslmode=require参数确保了SSL加密连接的建立。

[postgres@pg16 ~]$ psql postgresql://127.1:5432/postgres?sslmode=require
psql (16.4-ShawnYan)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=# \conninfo
You are connected to database "postgres" as user "postgres" on host "127.1" (address "127.0.0.1") at port "5432".
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
postgres=# 

也可,在命令行中重新建立带有SSL加密的连接。

[postgres@pg16 ~]$ psql
psql (16.4-ShawnYan)
Type "help" for help.

postgres=# \c "host=127.1 sslmode=require"
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
You are now connected to database "postgres" as user "postgres" on host "127.1" (address "127.0.0.1") at port "5432".
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" on host "127.1" (address "127.0.0.1") at port "5432".
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
postgres=# 

TLS 版本

在 CentOS 7 中,默认安装的 OpenSSL 版本为 1.0.2,该版本最高支持 TLSv1.2 版本。

对于新环境,推荐使用 Rocky Linux 9.4 系统,默认安装的是 OpenSSL 3.0 版本,支持 TLS v1.3 版本,可以获得更高的安全性和性能。

[postgres@pg16 ~]$ cat /etc/redhat-release 
Rocky Linux release 9.4 (Blue Onyx)
[postgres@pg16 ~]$ openssl version
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)

在 PG 中可以通过参数 ssl_max_protocol_version / ssl_min_protocol_version 控制 TLS 协议版本。

例如,指定最大版本为 TLSv1.2。

postgres=# show ssl_max_protocol_version ;
 ssl_max_protocol_version 
--------------------------
 
(1 row)

postgres=# \c "host=127.1 sslmode=require"
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
You are now connected to database "postgres" as user "postgres" on host "127.1" (address "127.0.0.1") at port "5432".

postgres=# alter system set ssl_max_protocol_version = 'TLSv1.2';
ALTER SYSTEM

postgres=# \c "host=127.1 sslmode=require"
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, compression: off)
You are now connected to database "postgres" as user "postgres" on host "127.1" (address "127.0.0.1") at port "5432".
postgres=# 

可以看到新建连接的协议版本为 TLSv1.2。

实践案例

在实际案例中,我们可以在PG数据库服务器端允许客户端自由选择 TLSv1.2 或者 TLSv1.3 版本。

比如,在 Java 代码实现中可以通过客户端属性进行控制。

TLSv1.2:

[postgres@pg16 ~]$ java -Djdk.tls.client.protocols=TLSv1.2 -cp .:postgresql-42.7.3.jar Main
Java Version: 1.8.0_422  (Red Hat, Inc.)
Driver: PostgreSQL JDBC Driver 42.7.3
Database: PostgreSQL 16.4-ShawnYan
Pid: 68698, UserName: postgres, DbName: postgres, State: active, Ssl: t, Version: TLSv1.2, Cipher: ECDHE-RSA-AES256-GCM-SHA384

TLSv1.3:

[postgres@pg16 ~]$ java -Djdk.tls.client.protocols=TLSv1.3 -cp .:postgresql-42.7.3.jar Main
Java Version: 1.8.0_422  (Red Hat, Inc.)
Driver: PostgreSQL JDBC Driver 42.7.3
Database: PostgreSQL 16.4-ShawnYan
Pid: 68716, UserName: postgres, DbName: postgres, State: active, Ssl: t, Version: TLSv1.3, Cipher: TLS_AES_256_GCM_SHA384

监控SSL连接

PostgreSQL提供了pg_stat_ssl系统视图,允许管理员监控当前的SSL连接状态。通过查询这个视图,可以获得关于SSL连接的详细信息,如协议版本、密码套件等。这有助于了解数据库的SSL使用情况,并收集当前加密连接的使用情况。

postgres=# table pg_stat_ssl;
  pid  | ssl | version |         cipher         | bits | client_dn | client_serial | issuer_dn 
-------+-----+---------+------------------------+------+-----------+---------------+-----------
 67602 | t   | TLSv1.3 | TLS_AES_256_GCM_SHA384 |  256 |           |               | 
(1 row)

小结

通过上述步骤,我们可以看到PostgreSQL中SSL的配置和使用是一个涉及多个步骤的过程。从编译安装阶段的配置选项,到生成SSL证书和密钥,再到配置数据库和监控SSL连接,每一步都至关重要。


更多PG新特性可参阅图书《快速掌握PostgreSQL版本新特性》

🌻 往期精彩 ▼


– / END / –

👉 这里可以找到我

如果这篇文章为你带来了灵感或启发,就请帮忙点『』or『在看』or『转发』吧,感谢!ღ( ´・ᴗ・` )~

最后修改时间:2024-08-13 10:21:40
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论