Postgresql – Enabling TLSv1 in postgres12 / openssl1.1.1f

postgresqlssltls-1.2

After upgrading a server to postgres12 / OpenSSL 1.1.1f (Ubuntu 20.04) I got tlsv1 alert protocol version error messages from a client using an old openssl 1.0.1 library supporting only tlsv1.

I thought setting ssl_min_protocol_version = 'TLSv1' in postgresql.conf should enable the protocol allowing that client to connect. However it does not. I used nmap to check for supported protocols and found only one section with the TLSv1.2 ciphers:

➜  ~ nmap --script ssl-enum-ciphers -p 5432 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-23 22:28 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000064s latency).

PORT     STATE SERVICE
5432/tcp open  postgresql
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|       TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 2048) - A
<snip>

I used this SE answer Ubuntu 20.04 – how to set lower SSL security level? to change the system default MinProtocol setting in openssl.cnf to TLSv1 and postgres picked up this setting (also the openssl1.0.1 client could connect with this setting):

➜  ~ sudo service postgresql restart
➜  ~ nmap --script ssl-enum-ciphers -p 5432 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-23 22:31 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000062s latency).

PORT     STATE SERVICE
5432/tcp open  postgresql
| ssl-enum-ciphers: 
|   TLSv1.0: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
<snip>
|   TLSv1.1: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
<snip>
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|       TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 2048) - A
<snip>

For curiosity I changed ssl_min_protocol_version = 'TLSv1.2' in postgresql.conf to see if the postgres server uses the intersection of the two configured ranges and after some debugging help from Laurenz i found that this setting was applied.

My question remained:

How can I configure my system so that postgres will accept TLSv1 through TLSv1.2 connections while keeping the openssl default MinProtocolsetting of TLSv1.2?

Best Answer

As Laurenz Albe pointed out, it is not possible to configure postgres to use a protocol version older than the MinProtocol specified in openssl.cnf.

It is however possible to make postgres use its own version of openssl.cfg. This way postgres can use TLSv1 without affecting the system default.

To achieve this I added the following line to the environment file in pg's config directory:

OPENSSL_CONF = '/etc/postgresql/12/main/openssl.cnf'

I then copied /etc/ssl/openssl.cnf to this directory and made the changes there i.e.:

# beginning of openssl.cnf
openssl_conf = default_conf

# end of openssl.cnf
[ default_conf ]

ssl_conf = ssl_sect

[ssl_sect]

system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT:@SECLEVEL=1

Now ssl_min_protocol_version = 'TLSv1' in postgresql.conf works and the rest of the system still uses the openssl default of TLSv1.2