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

[译文]为 PostgreSQL 设置 SSL 身份验证

原创 Hans-Jürgen Schönig 2021-06-23
2911

PostgreSQL 是一个安全的数据库,我们希望保持这种状态。因此,考虑使用 SSL 来加密客户端和服务器之间的连接是有道理的。这篇文章将帮助您正确设置 PostgreSQL 的 SSL 身份验证,并希望了解一些背景信息,使您的数据库更安全。

图片.png

使用 PostgreSQL 进行 SSL 认证

在这篇文章的最后,您应该能够以最简单的方式配置 PostgreSQL 并处理安全的客户端服务器连接。

为 OpenSSL 配置 PostgreSQL
设置 OpenSSL 要做的第一件事是更改 postgresql.conf。有几个与加密相关的参数:

ssl = on
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
#ssl_key_file = 'server.key'
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_min_protocol_version = 'TLSv1.2'
#ssl_max_protocol_version = ''
#ssl_dh_params_file = ''
#ssl_passphrase_command = ''
#ssl_passphrase_command_supports_reload = off

一旦可能ssl = on,服务器将协商 SSL 连接。其余参数定义密钥文件的位置、密码的强度等。请注意,开启 SSL 不需要重新启动数据库。可以通过简单的重新加载来设置变量。但是,您仍然需要重新启动,否则 PostgreSQL 将不接受 SSL 连接。对于某些用户来说,这是一个经常导致问题的重要点:

postgres=# SELECT pg_reload_conf();
  pg_reload_conf
----------------
  t
(1 row)
 
postgres=# SHOW ssl;
  ssl
-----
  on
(1 row)

该SHOW命令是确保设置确实已更改的简单方法。从技术上讲,此阶段不需要 pg_reload_conf()。无论如何都要稍后重新启动。我们只是重新加载以显示对变量的影响。

在下一步中,我们必须调整 pg_hba.conf 以确保 PostgreSQL 以安全的方式处理我们的连接:

# TYPE    DATABASE     USER      ADDRESS           METHOD
 
# "local" is for Unix domain socket connections only
local     all          all                         peer
host      all          all       127.0.0.1/32      scram-sha-256
host      all          all       ::1/128           scram-sha-256
hostssl   all          all       10.0.3.0/24       scram-sha-256``

然后重新启动数据库实例以确保启用了 SSL。

您接下来要做的是创建证书。为了简单起见,我们将在这里简单地创建自签名证书。但是,当然也可以用其他证书进行。下面是它的工作原理:


[postgres@node1 data]$ openssl req -new -x509 -days 365 \
     -nodes -text -out server.crt \
     -keyout server.key \
     -subj "/CN=cybertec-postgresql.com"
Generating a RSA private key
.......+++++
....................................................+++++
writing new private key to 'server.key'
-----

该证书的有效期为 365 天。接下来我们必须设置权限以确保可以使用证书。如果这些权限太宽松,服务器将不接受证书:

[postgres@node1 data]$ chmod og-rwx server.key

自签名证书很好。但是,要创建客户端可以验证其身份和来源的服务器证书,请首先创建证书签名请求和公钥/私钥文件:

[postgres@node1 data]$ openssl req -new -nodes -text \
     -out root.csr \
     -keyout root.key \
     -subj "/CN=cybertec-postgresql.com"
Generating a RSA private key
.................................+++++
....................+++++
writing new private key to 'root.key'
-----

同样,我们必须确保这些权限完全正确:

[postgres@node1 data]$ chmod og-rwx root.key

然后我们签署请求。要使用 OpenSSL 做到这一点,我们首先必须找出可以找到 openssl.cnf 的位置。我们已经看到它并不总是在同一个地方——所以请确保您使用正确的路径:

[postgres@node1 data]$ find / -name openssl.cnf \
     2> /dev/null
/etc/pki/tls/openssl.cnf

我们在签署请求时使用此路径:

[postgres@node1 data]$ openssl x509 -req -in root.csr \
     -text \
     -days 3650 \
     -extfile /etc/pki/tls/openssl.cnf \
     -extensions v3_ca \
     -signkey root.key -out root.crt
Signature ok
subject=CN = cybertec-postgresql.com
Getting Private key

让我们使用新的根权限创建证书:

[postgres@node1 data]$ openssl req -new -nodes -text \
     -out server.csr \
     -keyout server.key \
     -subj "/CN=cybertec-postgresql.com"
Generating a RSA private key
.....................+++++
...........................+++++
writing new private key to 'server.key'
[postgres@node1 data]$ chmod og-rwx server.key
[postgres@node1 data]$ openssl x509 -req \
     -in server.csr -text -days 365 \
     -CA root.crt -CAkey root.key -CAcreateserial \
     -out server.crt
Signature ok
subject=CN = cybertec-postgresql.com
Getting CA Private Key

server.crt并且server.key应该按照 postgresql.conf 中的配置存储在服务器上的数据目录中。

但是还有更多:root.crt应该存储在客户端上,以便客户端可以验证服务器的证书是否由证书颁发机构签名。root.key应离线存储以用于创建未来的证书。

需要以下文件:

图片.png

检查您的设置

现在所有证书都已就位,是时候重新启动服务器了:

[root@node1 ~]# systemctl restart postgresql-13

如果不重新启动,连接将失败并显示错误消息 (“psql: error: FATAL: no pg_hba.conf entry for host “10.0.3.200”, user “postgres”, database “test”, SSL off”).

但是,重新启动后,该过程应按预期工作:

[root@node1 ~]# su - postgres
[postgres@node1 ~]$ psql test -h 10.0.3.200
Password for user postgres:
psql (13.2)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
 
test=#

psql 表示连接已加密。要确定连接是否确实加密,我们需要检查 pg_stat_ssl 的内容:

postgres=# \d pg_stat_ssl
 
View "pg_catalog.pg_stat_ssl"
Column          | Type    | Collation | Nullable | Default
----------------+---------+-----------+----------+---------
pid             | integer |           |          |
ssl             | boolean |           |          |
version         | text    |           |          |
cipher          | text    |           |          |
bits            | integer |           |          |
compression     | boolean |           |          |
client_dn       | text    |           |          |
client_serial   | numeric |           |          |
issuer_dn       | text    |           |          |

让我们查询系统视图并查看它包含的内容:

test=# \x
Expanded display is on.
test=# SELECT * FROM pg_stat_ssl;
-[ RECORD 1 ]-+-----------------------
pid           | 16378
ssl           | t
version       | TLSv1.3
cipher        | TLS_AES_256_GCM_SHA384
bits          | 256
compression   | f
client_dn     |
client_serial |
issuer_dn     |

连接已成功加密。如果“ssl = true”,那么我们就成功了。

PostgreSQL 支持不同级别的 SSL

两个 SSL 设置不一定相同。有多种级别可让您控制所需的安全和保护级别。下表概述了 PostgreSQL 支持的 SSL 模式:

图片.png

开销实际上取决于您使用的模式。首先我们来看看一般的机制:

图片.png

现在的主要问题是:如何指定要使用的模式?答案是:它必须作为连接字符串的一部分隐藏,如下例所示:

[postgres@node1 data]$ psql "dbname=test host=10.0.3.200 user=postgres password=1234 sslmode=verify-ca"
psql: error: root certificate file "/var/lib/pgsql/.postgresql/root.crt" does not exist
Either provide the file or change sslmode to disable server certificate verification.

在这种情况下,verify-ca 不起作用,因为这样做必须将 root.* 文件复制到客户端,并且证书必须是允许正确验证目标服务器的证书。

加密你的整个服务器:PostgreSQL TDE

到目前为止,您已经学习了如何加密客户端和服务器之间的连接。但是,有时需要加密整个服务器,包括存储。PostgreSQL TDE 正是这样做的:

图片.png
PostgreSQL的透明数据加密

要了解更多信息,请查看我们关于PostgreSQL TDE的网站。我们提供完全加密的堆栈来帮助您实现最大的安全性。PostgreSQL TDE 可免费使用(开源)。

您可能还感兴趣的东西……

物化视图是包括 PostgreSQL 在内的大多数数据库的重要特性。它们可以帮助加速大型计算,或者至少可以缓存它们。

如果您想确保您的物化视图是最新的,并且如果您想立即阅读有关 PostgreSQL 的更多信息,请查看我们关于pg_timetable的博客,它向您展示了如何在 PostgreSQL 中安排作业。为什么 pg_timetable 如此有用?我们的调度程序确保相同的作业不会重叠,但如果相同的作业已经在运行,则不会再次执行。在长时间作业的情况下,使用调度程序非常重要——特别是如果你想使用物化视图。

作者:汉斯-于尔根·舍尼格
Hans-Jürgen Schönig 自 90 年代以来就有使用 PostgreSQL 的经验。他是 CYBERTEC 的首席执行官兼技术负责人,CYBERTEC 是该领域的市场领导者之一,自 2000 年以来已为全球无数客户提供服务。

文章来源:https://www.cybertec-postgresql.com/en/setting-up-ssl-authentication-for-postgresql/

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

评论