1. Introduction
The upcoming major release of PostgreSQL 13 has several important behavioral updates related to the TLS implementation. These updates may have some to your current PostgreSQL security deployment if you were considering to upgrade to 13 when it officially releases. Today I would like to do a quick summary of these updates.
2. Minimum TLS Version Changed to TLSv1.2
There are 2 server parameters in postgresql.conf
that influence the desired TLS versions to use during communication, ssl_min_protocol_version
and ssl_max_protocol_version
. In previous PG versions, the default value for ssl_min_protocol_version
was TLSv1
, in which many older versions of OpenSSL could support. In PG13, this default has been raised to TLSv1.2, which satisfies current industry’s best practice. This means that if your psql client is built using older version of OpenSSL, such as 1.0.0., the PG13 server by default will deny this TLS connection, until either you rebuild the psql client with newer version of OpenSSL, or you lower the ssl_min_protocol_version
back to TLSv1
. Lowering this default is strongly discouraged as older versions of TLS are not as secured and many industrial applications are communicating using TLSv1.2
as a standard requirement now.
3. New libpq connection parameters
There are also several updates to the libpq client side connection parameters related to TLS. See sub sections below:
3.1 ssl_min_protocol_version and ssl_max_protocol_version
The ssl_min_protocol_version
and ssl_max_protocol_version
parameters defined in the postgresql.conf
on the server side were not available in the libpq client side in the previous PG versions. This means that in previous versions, it was not possible for client to influence the desired version of TLS to used as it would always want to used the newest TLS versions to communicate with the server. This may not be ideal in some cases. In PG13, the same sets of parameters are added to the libpq client side as well such that the client can also play a part in determining the ideal TLS version for communication. These parameters can be specified to psql
like so:
psql -U user -d "sslmode=require dbname=postgres ssl_max_protocol_version=TLSv1.2" |
The second command in the above example sets minimum TLS protocol to TLSv1.3
, which means that this client would only want to communicate with a server that could support TLSv1.3 as minimum version requirement. TLSv1.3 is fairly new and not every PostgreSQL servers are built with this support. In this case, the client simply refuses to communicate. These parameters are great additions to the current libpq as they give the client the ability to enforce the desired TLS version to use rather than simply letting the server to decide, resulting in a much more secured environment.
3.2 channel_binding
Channel binding is a new feature introduced in PG13, in which the libpq client can optionally enable to further increase the security of the TLS connection. The channel_binding
parameter can be set to require
to enforce the channel binding feature, prefer
to only use channel binding if it is available or disable
to not use channel binding at all. prefer
is the default value for the new channel_binding
parameter.
The channel binding feature enforces trust between client and server so that Client informs the server whom it thinks it speaks to, and Server validates whether it is correct or not. This prevents an attacker who is able to capture users’ authentication credentials (e.g. OAuth tokens, session identifiers, etc) from reusing those credentials in another TLS sessions. In PG13, the channel binding is done by tying the user’s scram-sha-256
credentials to a unique fingerprint of the TLS session in which they are used (channel binding), so they cannot be reused in another TLS sessions initiated by the attacker.
To use this feature, we need to define a rule in pg_hba.conf
that uses scram-sha-256
as authentication method. Ex:
hostssl all all 127.0.0.1/32 scram-sha-256 |
also set the default password authentication method to scram-sha-256
in postgresql.conf
.
password_encryption = scram-sha-256 |
and then sets a scram-sha-256 password for the current user or another user in a existing psql connection
\password |
then finally, we can use psql with channel binding to connect to the server. Ex:
psql -U user -d "sslmode=require dbname=postgres channel_binding=require ssl_min_protocol_version=TLSv1.2" |
3.3 sslpassword
In previous version of PG, in a sslmode=verify-full
case, the client will need to specify its X509 certificate, private key and CA cert to complete the entire TLS authentication. In the case where the private key supplied by the client is encrypted with a password, the psql will prompt the user to enter it before proceeding with the TLS authentication. The new sslpassword
parameter allows the user to specify the password to the connection parameters without prompting the user to enter it. This is a useful addition, as the psql command could basically completes without having a human or a bot to enter the passphrase to unlock the private key. This parameter can be used like this:
psql -U user -d "sslmode=verify-full dbname=postgres sslrootcert=cacert.pem sslcert=client.pem sslkey=client.key sslpassword=mypass" |
4. Remove support for OpenSSL 0.9.8 and 1.0.0
Another major change is that PG13 will refuse to be built with OpenSSL versions 1.0.0 and 0.9.8 as these are very old and are no longer considered secured in today’s standard. If you are still using these OpenSSL versions, you will need to upgrade to newer or recent versions to be compatible with PG13.
5. Conclusion
PG13 brings many exciting new features and enhancements to PostgreSQL and many of these new changes need to be carefully assessed for potential incompatibility with the previous PG versions. Today, our focus is mainly on new updates related to TLS, which may have behavioral impacts to the existing deployment and the way existing client and server communicates using TLS. For the full changes and potential incompatibilities, visit the official change log here