Securing inter-node connections v6.3.1
PGD nodes connect directly to each other over the network to replicate changes. Without SSL, replication traffic is unencrypted and unauthenticated, leaving it exposed to interception and allowing unauthenticated peers to participate in replication. Configure SSL on each node to encrypt replication traffic and prevent unauthorized nodes from joining the cluster.
Setting up an authentication method
PGD supports two approaches for authenticating inter-node connections.
Note
Connection Manager reads the same server.crt configured for inter-node SSL. Using certificates that don't meet Connection Manager's requirements will prevent it from starting. See Meeting SSL certificate requirements for details.
As a best practice, use a dedicated database role for inter-node connections rather than the postgres superuser. Before joining nodes to the cluster, run the following on each node to create the role:
CREATE ROLE pgd_replication LOGIN IN ROLE bdr_superuser;
Use this role in the connection strings and pg_hba.conf rules shown in the following sections.
We recommend certificate authentication as it provides mutual authentication alongside encryption. If certificates aren't available in your environment, SCRAM-SHA-256 with Certificate Authority (CA) verification provides password-based authentication while still encrypting the connection.
Authenticating with certificates
Certificate authentication is the recommended approach. Client certificates provide both encryption and mutual authentication. Each node presents a certificate to prove its identity, and all traffic is encrypted in transit.
Provisioning certificates
Because each PGD node both accepts incoming replication connections and initiates outgoing ones, every node acts as both a server and a client. Each node needs server-side certificate files to accept connections and client-side certificate files to initiate them.
Make sure the following files are present in the data directory on each node. See SSL certificate setup in the PostgreSQL documentation for guidance on generating them.
server.crtandserver.key— the node's server certificate and private key.bdr_client.crt— the client certificate for the node.bdr_client.key— the private key for the client certificate. This file must not be world-readable.root.crt— the CA certificate used to verify both client and server certificates.
The certificates must also meet these requirements:
- The server's SSL certificate must be directly or indirectly signed by the CA in
root.crt. - The hostname or IP address in the connection must match the certificate's subject alternative name (SAN) or common name (CN).
- The CN of the client certificate must match the Postgres user making the PGD connection.
Note
Postgres doesn't currently support subject alternative names for IP addresses. If nodes connect by IP address rather than hostname, the IP address must match the CN field of the certificate.
Configuring certificate authentication
Enable SSL in
postgresql.confon each node:ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key'
Restart Postgres on each node to apply the change:
pg_ctl restart -D "$PGDATA"
Check the current connection string for each node:
SELECT node_name, interface_connstr FROM bdr.node_summary;
Use
bdr.alter_node_interface()to update each node's connection string with the SSL parameters. The function replaces the entire connection string, so include all existing parameters alongside the new SSL ones. Run it on every node in the group, including the node being changed. For example:SELECT bdr.alter_node_interface( 'node-1', 'host=host-1 port=5432 dbname=pgddb user=pgd_replication sslmode=verify-full sslcert=bdr_client.crt sslkey=bdr_client.key sslrootcert=root.crt' );
Add entries to each node's
pg_hba.confto permit inter-node connections:hostssl all pgd_replication <node_subnet>/24 cert hostssl replication pgd_replication <node_subnet>/24 cert
Replace
<node_subnet>with the actual subnet or IP range of your PGD nodes.Reload Postgres on each node to apply the
pg_hba.confchanges:pg_ctl reload -D "$PGDATA"
Authenticating with SCRAM-SHA-256 and CA verification
If client certificates aren't available, use password authentication while still encrypting the connection and verifying the server's certificate against a CA.
Provisioning certificates and credentials
Make sure the following are in place on each node:
server.crtandserver.keyin the data directory — the node's server certificate and private key. See SSL certificate setup in the PostgreSQL documentation for guidance on generating them.root.crtin the data directory — the CA certificate used to verify the server's SSL certificate.- A
.pgpassfile in the home directory of the Postgres process user, containing the correct password for each node. The file must have permissions0600or stricter. If permissions are too open, the file is silently ignored.
Configuring SCRAM-SHA-256 authentication
Enable SSL in
postgresql.confon each node:ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key'
Restart Postgres on each node to apply the change:
pg_ctl restart -D "$PGDATA"
Use
bdr.alter_node_interface()to update each node's connection string. The function replaces the entire connection string, so include all existing parameters alongside the new SSL ones. Run it on every node in the group, including the node being changed.SELECT bdr.alter_node_interface( 'node-1', 'host=host-1 port=5432 dbname=pgddb user=pgd_replication sslmode=verify-ca sslrootcert=root.crt' );
Add entries to each node's
pg_hba.conffor inter-node connections:hostssl all pgd_replication <node_subnet>/24 scram-sha-256 hostssl replication pgd_replication <node_subnet>/24 scram-sha-256
Replace
<node_subnet>with the actual subnet or IP range of your PGD nodes.Reload Postgres on each node to apply the
pg_hba.confchanges:pg_ctl reload -D "$PGDATA"
Verifying the configuration
After configuring SSL, confirm that replication connections are encrypted and that all nodes are active. Run these queries on any node in the cluster.
Verify that replication connections are using SSL:
SELECT pid, ssl, version, cipher, bits FROM pg_stat_ssl JOIN pg_stat_replication USING (pid);
Outputpid | ssl | version | cipher | bits -----+-----+---------+------------------------+------ 51 | t | TLSv1.3 | TLS_AES_256_GCM_SHA384 | 256 50 | t | TLSv1.3 | TLS_AES_256_GCM_SHA384 | 256 (2 rows)
A successful result shows one row per replication connection, with
sslset tot. This output confirms encryption is active, but doesn't show which authentication method is in use.Confirm the authentication method configured in
pg_hba.conf:SELECT type, database, user_name, address, auth_method FROM pg_hba_file_rules WHERE auth_method IN ('cert', 'scram-sha-256');
Outputtype | database | user_name | address | auth_method ---------+---------------+------------+------------+--------------- hostssl | {all} | {pgd_replication} | 172.20.0.0 | scram-sha-256 hostssl | {replication} | {pgd_replication} | 172.20.0.0 | scram-sha-256 (2 rows)The rows you added appear with the
auth_methodyou configured, for examplecertorscram-sha-256.Confirm all nodes are still replicating normally:
SELECT node_name, peer_state_name, peer_target_state_name FROM bdr.node_summary;
Outputnode_name | peer_state_name | peer_target_state_name -----------+-----------------+------------------------ node-1 | ACTIVE | ACTIVE node-3 | ACTIVE | ACTIVE node-2 | ACTIVE | ACTIVE (3 rows)
All nodes appear as
ACTIVEin both state columns.