By default, PostgreSQL only accepts connections from localhost using peer or ident authentication. Enabling remote access requires two configuration changes: editing postgresql.conf to listen on a network interface, and editing pg_hba.conf to permit remote connections from specific hosts or subnets. Beyond network access, encrypting the connection with SSL/TLS is essential for any deployment where database traffic crosses an untrusted network — preventing credentials and query data from being intercepted. PostgreSQL has built-in SSL support using OpenSSL and can use certificates from Let’s Encrypt, an internal CA, or self-signed certificates. This guide covers enabling remote access, configuring SSL, enforcing SSL-only connections, and creating a client certificate for mutual TLS authentication.

Prerequisites

  • PostgreSQL 16 installed on RHEL 9
  • A server certificate and key (self-signed or from a CA)

Step 1 — Generate SSL Certificates for PostgreSQL

# Self-signed certificate for PostgreSQL (valid 2 years)
openssl req -x509 -nodes -days 730 -newkey rsa:4096 
    -keyout /var/lib/pgsql/16/data/server.key 
    -out    /var/lib/pgsql/16/data/server.crt 
    -subj "/CN=db.example.com"

chown postgres:postgres /var/lib/pgsql/16/data/server.key
chmod 600               /var/lib/pgsql/16/data/server.key

Step 2 — Enable SSL in postgresql.conf

# /var/lib/pgsql/16/data/postgresql.conf
listen_addresses = '*'          # Listen on all interfaces (or specific IP)
ssl              = on
ssl_cert_file    = 'server.crt'
ssl_key_file     = 'server.key'
# For CA-signed cert, also set:
# ssl_ca_file    = 'root.crt'

Step 3 — Configure pg_hba.conf for Remote SSL Access

# /var/lib/pgsql/16/data/pg_hba.conf

# TYPE  DATABASE   USER          ADDRESS            METHOD
# Local connections — peer auth for OS user postgres
local   all        postgres                         peer

# SSL-required connection from application server 10.0.1.20
hostssl myapp      myapp_user    10.0.1.20/32       scram-sha-256

# SSL required from entire subnet
hostssl all        all           192.168.1.0/24     scram-sha-256

# Reject non-SSL remote connections
hostnossl all      all           0.0.0.0/0          reject
systemctl restart postgresql-16

Step 4 — Open Firewall

firewall-cmd --permanent --add-service=postgresql
firewall-cmd --reload

Step 5 — Test SSL Connection from Remote Client

# From the application server (10.0.1.20)
# sslmode=require forces SSL; sslmode=verify-full also verifies the cert CN
psql "host=db.example.com dbname=myapp user=myapp_user sslmode=require"

# Verify SSL is in use from within psql
conninfo
# Should show: SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384)

Step 6 — Enforce SSL for a Specific User

-- Force SSL for a user at the role level
ALTER USER myapp_user SET ssl_cert_file = '';  -- SSL is enforced via pg_hba.conf

-- Verify the user's connection settings
SELECT usename, usesuper, valuntil FROM pg_user WHERE usename = 'myapp_user';

Conclusion

Enabling remote access to PostgreSQL on RHEL 9 requires coordinated changes to both postgresql.conf (listening interface and SSL certificates) and pg_hba.conf (which hosts/users can connect and how). Using hostssl entries and hostnossl ... reject enforces that all remote connections must be SSL-encrypted, protecting credentials and query data in transit. The scram-sha-256 authentication method is the most secure password-based option available in PostgreSQL 16.

Next steps: How to Configure PostgreSQL Streaming Replication on RHEL 9, How to Back Up PostgreSQL with pg_dump on RHEL 9, and How to Install pgAdmin 4 on RHEL 9.