6.8 Ensure TLS is enabled and configured correctly

Information

TLS on a PostgreSQL server should be enabled and configured to encrypt TCP traffic to and from the server.

Rationale:

If TLS is not enabled and configured correctly, this increases the risk of data being compromised in transit.

Impact:

A self-signed certificate can be used for testing, but a certificate signed by a certificate authority (CA) (either one of the global CAs or a local one) should be used in production so that clients can verify the server's identity. If all the database clients are local to the organization, using a local CA is recommended.

To ultimately enable and enforce TLS authentication for the server, appropriate hostssl records must be added to the pg_hba.conf file. Be sure to reload PostgreSQL after any changes (restart not required).

Note: The hostssl record matches connection attempts made using TCP/IP, but only when the connection is made with TLS encryption. The host record matches attempts made using TCP/IP, but allows both TLS and non-TLS connections. The hostnossl record matches attempts made using TCP/IP, but only those without TLS. Care should be taken to enforce TLS as appropriate.

Solution

For this example, and ease of illustration, we will be using a self-signed certificate (generated via openssl) for the server, and the PostgreSQL defaults for file naming and location in the PostgreSQL $PGDATA directory.

# whoami
postgres
# # create new certificate and enter details at prompts
# openssl req -new -text -out server.req
Generating a 2048 bit RSA private key
.....................+++
..................................................................+++
writing new private key to 'privkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Ohio
Locality Name (eg, city) [Default City]:Columbus
Organization Name (eg, company) [Default Company Ltd]:Me Inc
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:my.me.inc
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# # remove passphrase (required for automatic server start up, if not using 'ssl_passphrase_command')
# openssl rsa -in privkey.pem -out server.key && rm privkey.pem
Enter pass phrase for privkey.pem:
writing RSA key

# # modify certificate to self signed, generate .key and .crt files
# openssl req -x509 -in server.req -text -key server.key -out server.crt

# # copy .key and .crt files to appropriate location, here default $PGDATA
$ cp server.key server.crt $PGDATA

# # restrict file mode for server.key
$ chmod og-rwx server.key

Edit the PostgreSQL configuration file postgresql.conf to ensure the following items are set. Again, we are using defaults. Note that altering these parameters will require restarting the cluster.

# (change requires restart)
ssl = on

# force clients to use TLS v1.3 or newer
ssl_min_protocol_version = 'TLSv1.3'

# (change requires restart)
ssl_cert_file = 'server.crt'

# (change requires restart)
ssl_key_file = 'server.key'

Finally, restart PostgreSQL and confirm ssl using commands outlined in Audit Procedures:

postgres=# show ssl;
ssl
-----
on
(1 row)

Default Value:

Note that server.crt and server.key are the default names used by PostgreSQL. These files can be named otherwise, just ensure you update the postgresql.conf to use these new names. The current names can be found via SQL:

postgres=# select name, setting from pg_settings where name like 'ssl%file';

---------------------------------

| name | setting |

|---------------------------------|

| ssl_ca_file | |

| ssl_cert_file | server.crt |

| ssl_crl_file | |

| ssl_dh_params_file | |

| ssl_key_file | server.key |

---------------------------------

(5 rows)

See Also

https://workbench.cisecurity.org/benchmarks/14977

Item Details

Category: ACCESS CONTROL, IDENTIFICATION AND AUTHENTICATION, SYSTEM AND COMMUNICATIONS PROTECTION

References: 800-53|AC-17(2), 800-53|IA-5, 800-53|IA-5(1), 800-53|SC-8, 800-53|SC-8(1), CSCv7|14.4

Plugin: PostgreSQLDB

Control ID: e0efca1d5410cfc3e32098a0b22503c0d971691a71d62bc39ebf3887ee8e5b72