Mutual TLS Authentication for Postgres
Resources :
- https://www.postgresql.org/docs/current/ssl-tcp.html
- https://github.com/max-lt/client-tls-authentication
- https://nordic-institute.atlassian.net/wiki/spaces/XRDKB/pages/187432961/How+To+Configure+PostgreSQL+To+Use+Mutual+TLS
- https://documentation.ubuntu.com/server/how-to/databases/install-postgresql/index.html
This article will show you how to secure your Postgres database connection.
Generate self-signed certificates
1. Create a Root CA with an EC Key
Generate an EC private key for the root CA
openssl ecparam -name prime256v1 -genkey -noout -out root.key
Alternatively, you can use the
secp384r1
orsecp256k1
curve.
Create a certificate signing request (CSR) for the root CA
openssl req -new -nodes -text -out root.csr -key root.key -subj "/CN=rootCA"
Sign the root certificate
openssl x509 -req -in root.csr -text -days 3650 -signkey root.key -out root.crt
2. Create a Server Certificate with an EC Key
Generate an EC private key for the server
openssl ecparam -name prime256v1 -genkey -noout -out server.key
Create a CSR for the server
openssl req -new -nodes -text -out server.csr -key server.key -subj "/CN=server"
Sign the server certificate with the root CA
openssl x509 -req -in server.csr -text -days 365 \
-CA root.crt -CAkey root.key -CAcreateserial -out server.crt
3. Create a Client Certificate with an EC Key
You must create a new certificate for each client.
Generate an EC private key for the client
openssl ecparam -name prime256v1 -genkey -noout -out client.key
Create a CSR for the client
openssl req -new -nodes -text -out client.csr -key client.key -subj "/CN=client"
Sign the client certificate with the root CA
openssl x509 -req -in client.csr -text -days 365 \
-CA root.crt -CAkey root.key -CAcreateserial -out client.crt
Verifying the Certificates
Verify the root certificate
openssl x509 -in root.crt -text -noout
Verify the server certificate
openssl x509 -in server.crt -text -noout
Configure Postgres
Enable SSL
Edit the postgresql.conf
file and set the following parameters:
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt'
Edit the pg_hba.conf
file and add the following line:
hostssl all all 127.0.0.1/32 scram-sha-256 clientcert=verify-ca
From the Postgres documentation:
This option can be set to verify-ca or verify-full. Both options require the client to present a valid (trusted) SSL certificate, while verify-full additionally enforces that the cn (Common Name) in the certificate matches the username or an applicable mapping.
Restart Postgres
systemctl restart postgresql