# 34.19. SSL Support

34.19.1. Client Verification of Server Certificates

34.19.2. Client Certificates

34.19.3. Protection Provided in Different Modes

34.19.4. SSL Client File Usage

34.19.5. SSL Library Initialization

PostgreSQL has native support for using SSL connections to encrypt client/server communications for increased security. SeeSection 19.9for details about the server-side SSL functionality.

libpq reads the system-wide OpenSSL configuration file. By default, this file is namedopenssl.cnfand is located in the directory reported byopenssl version -d. This default can be overridden by setting environment variableOPENSSL_CONFto the name of the desired configuration file.

# 34.19.1. Client Verification of Server Certificates

By default, PostgreSQL will not perform any verification of the server certificate. This means that it is possible to spoof the server identity (for example by modifying a DNS record or by taking over the server IP address) without the client knowing. In order to prevent spoofing, the client must be able to verify the server's identity via a chain of trust. A chain of trust is established by placing a root (self-signed) certificate authority (CA) certificate on one computer and a leaf certificatesignedby the root certificate on another computer. It is also possible to use an “intermediate” certificate which is signed by the root certificate and signs leaf certificates.

To allow the client to verify the identity of the server, place a root certificate on the client and a leaf certificate signed by the root certificate on the server. To allow the server to verify the identity of the client, place a root certificate on the server and a leaf certificate signed by the root certificate on the client. One or more intermediate certificates (usually stored with the leaf certificate) can also be used to link the leaf certificate to the root certificate.

Once a chain of trust has been established, there are two ways for the client to validate the leaf certificate sent by the server. If the parametersslmodeis set toverify-ca, libpq will verify that the server is trustworthy by checking the certificate chain up to the root certificate stored on the client. Ifsslmodeis set toverify-full, libpq 将验证服务器主机名是否与存储在服务器证书中的名称匹配。如果无法验证服务器证书,SSL 连接将失败。验证完整建议在大多数安全敏感环境中使用。

验证完整模式下,主机名与证书的主题备用名称属性匹配,如果没有类型的主题备用名称,则与通用名称属性匹配域名系统名称存在。如果证书的名称属性以星号 (*),星号将被视为通配符,它​​将匹配所有字符除了一个点(.)。这意味着证书将不匹配子域。如果使用 IP 地址而不是主机名进行连接,则 IP 地址将被匹配(不进行任何 DNS 查找)。

要允许服务器证书验证,必须在文件中放置一个或多个根证书~/.postgresql/root.crt在用户的主目录中。(在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\root.crt.) 如果需要将服务器发送的证书链链接到客户端上存储的根证书,还应将中间证书添加到文件中。

证书吊销列表 (CRL) 条目也会被检查~/.postgresql/root.crl存在(%APPDATA%\postgresql\root.crl在 Microsoft Windows 上)。

可以通过设置连接参数来更改根证书文件和 CRL 的位置sslrootcertsslcrlor the environment variablesPGSSLROOTCERTandPGSSLCRL.sslcrldiror the environment variablePGSSLCRLDIRcan also be used to specify a directory containing CRL files.

# Note

For backwards compatibility with earlier versions of PostgreSQL, if a root CA file exists, the behavior ofsslmode=requirewill be the same as that ofverify-ca, meaning the server certificate is validated against the CA. Relying on this behavior is discouraged, and applications that need certificate validation should always useverify-caorverify-full.

# 34.19.2. Client Certificates

If the server attempts to verify the identity of the client by requesting the client's leaf certificate, libpq will send the certificates stored in file~/.postgresql/postgresql.crtin the user's home directory. The certificates must chain to the root certificate trusted by the server. A matching private key file~/.postgresql/postgresql.keymust also be present. The private key file must not allow any access to world or group; achieve this by the commandchmod 0600 ~/.postgresql/postgresql.key.在 Microsoft Windows 上,这些文件被命名为%APPDATA%\postgresql\postgresql.crt%APPDATA%\postgresql\postgresql.key,并且没有特殊的权限检查,因为该目录被假定为安全的。证书和密钥文件的位置可以被连接参数覆盖sslcertsslkey或环境变量PGSSL证书PGSSLKEY.

第一张证书在postgresql.crt必须是客户端的证书,因为它必须与客户端的私钥匹配。可以选择将“中间”证书附加到文件中——这样做可以避免在服务器上存储中间证书(ssl_约_文件)。

证书和密钥可以是 PEM 或 ASN.1 DER 格式。

密钥可以明文存储或使用 OpenSSL 支持的任何算法(如 AES-128)使用密码加密。如果密钥是加密存储的,那么密码可以在ssl密码连接选项。如果提供了加密密钥并且ssl密码如果选项不存在或为空,则 OpenSSL 将通过交互方式提示输入密码,并带有输入 PEM 密码:prompt if a TTY is available. Applications can override the client certificate prompt and the handling of thesslpasswordparameter by supplying their own key password callback; seePQsetSSLKeyPassHook_OpenSSL.

For instructions on creating certificates, seeSection 19.9.5.

# 34.19.3. Protection Provided in Different Modes

The different values for thesslmodeparameter provide different levels of protection. SSL can provide protection against three types of attacks:

Eavesdropping

If a third party can examine the network traffic between the client and the server, it can read both connection information (including the user name and password) and the data that is passed. SSL uses encryption to prevent this.

Man-in-the-middle (MITM)

If a third party can modify the data while passing between the client and server, it can pretend to be the server and therefore see and modify dataeven if it is encrypted. The third party can then forward the connection information and data to the original server, making it impossible to detect this attack. Common vectors to do this include DNS poisoning and address hijacking, whereby the client is directed to a different server than intended. There are also several other attack methods that can accomplish this. SSL uses certificate verification to prevent this, by authenticating the server to the client.

Impersonation

If a third party can pretend to be an authorized client, it can simply access data it should not have access to. Typically this can happen through insecure password management. SSL uses client certificates to prevent this, by making sure that only holders of valid certificates can access the server.

For a connection to be known SSL-secured, SSL usage must be configured onboth the client and the serverbefore the connection is made. If it is only configured on the server, the client may end up sending sensitive information (e.g., passwords) before it knows that the server requires high security. In libpq, secure connections can be ensured by setting thesslmodeparameter toverify-fullorverify-ca, and providing the system with a root certificate to verify against. This is analogous to using anhttpsURL for encrypted web browsing.

Once the server has been authenticated, the client can pass sensitive data. This means that up until this point, the client does not need to know if certificates will be used for authentication, making it safe to specify that only in the server configuration.

All SSL options carry overhead in the form of encryption and key-exchange, so there is a trade-off that has to be made between performance and security.Table 34.1illustrates the risks the differentsslmodevalues protect against, and what statement they make about security and overhead.

Table 34.1. SSL Mode Descriptions

sslmode Eavesdropping protection MITM protection Statement
disable No No I don't care about security, and I don't want to pay the overhead of encryption.
allow Maybe No I don't care about security, but I will pay the overhead of encryption if the server insists on it.
prefer Maybe No I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it.
require Yes No I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want.
验证ca 取决于CA策略 我希望我的数据加密,我接受开销。我想确保连接到我信任的服务器。
验证完整 我希望我的数据加密,我接受开销。我希望确保连接到我信任的服务器,并且它是我指定的服务器。

两者的区别验证ca验证完整取决于根CA的策略。如果使用公共CA,验证ca允许连接到其他人可能已经在CA注册了。在这种情况下,验证完整应该一直使用。如果使用本地CA,甚至是自签名证书,请使用验证ca通常提供足够的保护。

的默认值sslmode更喜欢.如表中所示,从安全角度来看,这没有任何意义,它只承诺在可能的情况下增加性能开销。它仅作为向后兼容性的默认设置提供,不建议在安全部署中使用。

# 34.19.4.SSL客户端文件使用

表34.2总结与客户端上的SSL设置相关的文件。

Table 34.2. Libpq/Client SSL File Usage

File Contents Effect
~/.postgresql/postgresql.crt client certificate sent to server
~/.postgresql/postgresql.key client private key proves client certificate sent by owner; does not indicate certificate owner is trustworthy
~/.postgresql/root.crt trusted certificate authorities checks that server certificate is signed by a trusted certificate authority
~/.postgresql/root.crl certificates revoked by certificate authorities server certificate must not be on this list

# 34.19.5. SSL Library Initialization

If your application initializeslibssland/orlibcryptolibraries and libpq is built with SSL support, you should callPQinitOpenSSLto tell libpq that thelibssland/orlibcryptolibraries have been initialized by your application, so that libpq will not also initialize those libraries.

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 的应用程序可能更可取。