How is possible to configure TLSv1.1 protocol for SSL connection in PostgreSQL?
@BrianEfting was correct, you can specify the appropriate cipher suites to only allow TLSv1.2 which should fit your PCI-DSS 3.1 specification needs.
Using a cipher list like this in the ssl_ciphers
option in your postgresql.conf
:
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
along with setting ssl_prefer_server_ciphers=true
, should be sufficient to allow only TLSv1.2 connections.
You can verify this using SSLyze which knows about the PostgreSQL protocol.
To test, I used the following command:
./sslyze.py --sslv2 --sslv3 --tlsv1 --tlsv1_1 --tlsv1_2 localhost:5432 --starttls=postgres --hide_rejected_ciphers
Which gave the output below under PostgreSQL 9.4 on Debian Wheezy showing that all cipher suites except for the TLSv1.2 ciphers specified were rejected, which should satisfy the requirements of PCI-DSS 3.1 by using TLSv1.1 or greater.
postgres@pgsqlsec4:~/sslyze$ ./sslyze.py --sslv2 --sslv3 --tlsv1 --tlsv1_1 --tlsv1_2 localhost:5432 --starttls=postgres --hide_rejected_ciphers
AVAILABLE PLUGINS
-----------------
PluginCompression
PluginHeartbleed
PluginChromeSha1Deprecation
PluginSessionRenegotiation
PluginOpenSSLCipherSuites
PluginSessionResumption
PluginHSTS
PluginCertInfo
CHECKING HOST(S) AVAILABILITY
-----------------------------
localhost:5432 => ::1:5432
SCAN RESULTS FOR LOCALHOST:5432 - ::1:5432
------------------------------------------
* SSLV2 Cipher Suites:
Server rejected all cipher suites.
* TLSV1_2 Cipher Suites:
Preferred:
ECDHE-RSA-AES128-GCM-SHA256 ECDH-256 bits 128 bits
Accepted:
ECDHE-RSA-AES256-SHA384 ECDH-256 bits 256 bits
ECDHE-RSA-AES256-GCM-SHA384 ECDH-256 bits 256 bits
DHE-RSA-AES256-SHA256 DH-1024 bits 256 bits
DHE-RSA-AES256-GCM-SHA384 DH-1024 bits 256 bits
ECDHE-RSA-AES128-SHA256 ECDH-256 bits 128 bits
ECDHE-RSA-AES128-GCM-SHA256 ECDH-256 bits 128 bits
DHE-RSA-AES128-SHA256 DH-1024 bits 128 bits
DHE-RSA-AES128-GCM-SHA256 DH-1024 bits 128 bits
* TLSV1_1 Cipher Suites:
Server rejected all cipher suites.
* TLSV1 Cipher Suites:
Server rejected all cipher suites.
* SSLV3 Cipher Suites:
Server rejected all cipher suites.
SCAN COMPLETED IN 0.73 S
------------------------
postgres@pgsqlsec4:~/sslyze$
From the following link:
18.3. Connections and Authentication (PostgreSQL 9.4 Manual)
It would appear that you can use the ssl_ciphers
option to specify your list of accepted ciphers. And it mentions that it follows whatever your version of OpenSSL supports.
And in this link:
OpenSSL Ciphers (OpenSSL.org)
Mentions that there is no specific ciphersuite for TLSv1.1 but you can specify TLSv1.2.
Meanwhile, starting from Postgres 12, it's possible to force the minimal SSL/TLS encryption level at the server side by tweaking the ssl_min_protocol_version` parameter.
According to this documentation page valid values are currently: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3.