01 /简介/

🚀TLS 是大多数应用程序中最常用的安全协议之一,但也鲜为人知🌏。在这篇博客中,我将简要解释TLS的概念,以及如何将其配置为使用兼容的OpenSSL库编译的Postgres 15版本。💐

02 /PostgreSQL 服务器端设置/

这些是postgresql.conf中与TLS相关的TLS设置。

🔔 请注意,这些参数以前缀 SSL 开头,这是一个可与 TLS(较新术语)互换使用的术语。两者都指同一件事。

#ssl = off
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
#ssl_crl_dir = ''
#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,ssl_ca_file,ssl_cert_file,ssl_key_file,可能还有ssl_passphrase_command。例如:

ssl = on
ssl_ca_file = '/home/user/cert/cacert.pem'
ssl_cert_file = '/home/user/cert/server.pem'
ssl_key_file = '/home/user/cert/server.key'
ssl_passphrase_command = 'echo passphrase'

💁这些基本 TLS 参数告诉 Postgres 您希望在服务器上启用 TLS,并提供证书颁发机构 (CA) 证书文件、实体证书文件和私钥文件的路径。这3个文件通常被称为X509证书,主要用于保证客户端和服务器之间的信任。

📕CA 证书文件 (ssl_ca_file) 是信任根,您可以使用 openSSL 为您的组织生成一个证书,并使用它来创建和签署其他实体证书以供应用程序使用。

📕实体证书(ssl_cert_file)和私钥(ssl_key_file)形成一个pair,在某种意义上,证书本身包含公钥,而私钥文件包含私钥。这些密钥用于 TLS 握手期间的异步身份验证。实体证书通常使用在 ssl_ca_file 中配置的相同 CA 证书文件签名,这样它就可以被信任。也可以使用 openssl 生成和签名私钥和实体证书文件。

 🔧ssl_passphrase_command用于获取密码短语以解密ssl_key_file(如果在生成时已加密)。

请参阅此处🔗 的这篇博客文章📝,了解如何使用 openssl 创建和签署这些证书文件,以及对其余大部分默认 TLS 相关参数的简短说明。

03 /PostgreSQL 服务器端pg_hba设置/

除了上述主要设置外, 😆您还需要配置 pg_hba.conf 以限制哪些连接需要 TLS,哪些不需要。对于大多数人来说,这些设置通常更复杂😅。启用 TLS 后,可能涉及 2 个身份验证;一个涉及TLS握手(以验证客户端和服务器之间的信任),另一个涉及PG中以检查连接用户是否被授权。

请考虑以下示例:

hostssl   mydatabase myuser       192.168.1.0/24     trust
hostssl   mydatabase myuser2      192.168.1.0/24     trust clientcert=verify-ca
hostssl   mydatabase myuser3      192.168.1.0/24     password clientcert=verify-ca
hostssl   mydatabase myuser4      192.168.1.0/24     cert clientcert=verify-ca
hostnossl mydatabase myuser5      127.0.0.1/32       trust

🔨hostssl mydatabase myuser 192.168.1.0/24 trust

💡意味着只要myuser使用TLS在192.168.1.0网络中连接,myuser就会立即获得访问mydatabase的权限。

🔨hostssl mydatabase myuser2 192.168.1.0/24 trust clientcert=verify-ca

🔔表示如果 myuser2 使用 TLS 在 192.168.1.0 网络中连接,则 myuser2 需要提供自己的 X509 证书,服务器将使用 ssl_ca_file 中配置的 CA 证书验证客户端证书。如果证书可以信任,则 myuser2 将被授予对 mydatabase 的访问权限。

🔨hostssl mydatabase myuser3 192.168.1.0/24 password clientcert=verify-ca

💡表示如果 myuser3 使用 TLS 在 192.168.1.0 网络中连接,则 myuser3 需要提供自己的 X509 证书,服务器将使用 ssl_ca_file 中配置的 CA 证书验证客户端证书。如果证书可以信任,则 myuser3 将提示输入密码。如果密码匹配,则 myuser3 将被授予访问 mydatabase 的权限。

🔨hostssl mydatabase myuser4 192.168.1.0/24 cert clientcert=verify-ca

🔔表示如果 myuser4 使用 TLS 在 192.168.1.0 网络中连接,则 myuser4 需要提供自己的 X509 证书,服务器将使用 ssl_ca_file 中配置的 CA 证书验证客户端证书。如果证书可以信任,则 PG 将读取客户端提供的证书中的公用名 (CN) 字段,并检查它是否与连接用户的用户名匹配,如果匹配,则 user4 将有权访问 mydatabase。

🔨hostnossl mydatabase myuser5 127.0.0.1/32 trust

💡意味着如果 myuser5 在 127.0.0.1 localhost 中不使用 TLS 连接,myuser5 将只被授予对 mydatabase 的访问权限。

04 /PostgreSQL 客户端 TLS 选项/

大多数情况下,当 psql 客户端连接到启用了 TLS 的 Postgres 服务器时,是 psql 客户端将验证 Postgres 服务器发送的实体证书(在 postgresql.conf 中ssl_cert_file配置)。💁换句话说,客户端验证服务器。当然,psql 客户端还需要具有 CA 证书的副本(或由公共根 CA 签名的子 CA 证书),客户端可以使用该副本在握手期间🤝验证服务器的证书。

🌏这类似于用户在浏览器上连接到 https 网站。例如,Web 服务器 google.ca 握手期间🤝将其服务器证书发送到您的浏览器,浏览器将使用浏览器附带的许多内置 CA 证书来验证此证书。如果证书可以信任,则允许您连接。如果没有,它会给你一个警告页面,说“你的连接不是私有的”,你可以选择继续或不继续。

使用 psql 客户端,您可以指定要发送到服务器的证书和用于验证服务器证书的 CA 证书。

psql -U myuser2 -h 192.168.1.123 -d "sslmode=verify-ca dbname=mydatabase sslrootcert=/home/user/cert/cacert.pem sslcert=/home/user/cert/client.pem sslkey=/home/user/cert/client.key"

 🗺️这意味着 psql 客户端将使用 sslrootcert 中指定的 CA 证书验证服务器的证书。🔔由于服务器还要求客户端提供证书(因为 pg_hba.conf 中的 clientcert=verify-ca),客户端会将 sslcert 中指定的证书发送到服务器进行相互身份验证。