Securing inter-node connections#

PGDノードはネットワークを介して互いに直接接続して、変更をレプリケートします。 SSLがないと、レプリケーショントラフィックは暗号化されず認証されないため、傍受にさらされたままになり、未認証のピアがレプリケーションに参加できます。各ノードでSSLを構成して、レプリケーショントラフィックを暗号化し、無許可のノードがクラスターに参加するのを防ぎます。

認証方法の設定#

PGDは、ノード間接続を認証するための2つのアプローチをサポートしています。

注釈

接続マネージャーは、ノード間SSL用に構成されたものと同じ`server.crt` を読み取ります。接続マネージャーの要件を満たさない証明書を使用すると、接続マネージャーが起動できません。詳細は、 SSL証明書要件を満たす を参照してください。

ベストプラクティスとして、ノード間接続には、postgres スーパーユーザーではなく専用のデータベースロールを使用します。ノードをクラスターに参加させる前に、各ノードで次を実行してロールを作成します。

CREATE ROLE pgd_replication LOGIN IN ROLE bdr_superuser;

このロールは、以降のセクションで示す接続文字列とpg_hba.conf ルールで使用します。

証明書認証は、暗号化とともに相互認証を提供するため、お勧めします。環境で証明書が使用できない場合、認証局CA検証を備えたSCRAM-SHA-256は、接続を暗号化しながらパスワードベースの認証を提供します。

証明書を使用した認証#

証明書認証が推奨されるアプローチです。クライアント証明書は、暗号化と相互認証の両方を提供します。各ノードはそのIDを証明する証明書を提示し、すべてのトラフィックは転送中に暗号化されます。

プロビジョニング証明書#

各PGDノードは着信レプリケーション接続を受け入れ、発信接続を開始するため、すべてのノードがサーバーとクライアントの両方として機能します。各ノードには、接続を受け入れるためのサーバーサイドの証明書ファイルと、接続を開始するためのクライアントサイドの証明書ファイルが必要です。

次のファイルが各ノードのデータディレクトリに存在することを確認します。それらを生成するためのガイダンスについては、PostgreSQLドキュメントの SSL certificate setup を参照してください。

  • server.crt およびserver.key — ノードのサーバー証明書とプライベートキー。

  • bdr_client.crt —ノードのクライアント証明書。

  • bdr_client.key — クライアント証明書のプライベートキー。このファイルは、誰でも読み取り可能であってはなりません。

  • root.crt - クライアントとサーバー証明書の両方を検証するために使用されるCA証明書。

証明書は次の要件も満たす必要があります。

  • サーバーのSSL証明書は、root.crt のCAによって直接または間接的に署名される必要があります。

  • 接続のホスト名またはIPアドレスは、証明書のサブジェクト代替名SANまたは共通名CNと一致する必要があります。

  • クライアント証明書のCNは、PGD接続を行うPostgresユーザーと一致する必要があります。

注釈

Postgresは、現在IPアドレスのサブジェクトの代替名をサポートしていません。ノードがホスト名ではなくIPアドレスで接続する場合、IPアドレスは証明書のCNフィールドと一致する必要があります。

証明書認証の構成#

  1. 各ノードのpostgresql.conf でSSLを有効にします。

ssl = on
ssl_cert_file = server.crt
ssl_key_file = server.key

各ノードでPostgresを再起動して、変更を適用します。

pg_ctl restart -D "$PGDATA"
  1. 各ノードの現在の接続文字列を確認します。

SELECT node_name, interface_connstr FROM bdr.node_summary;
  1. bdr.alter_node_interface() を使用して、各ノードの接続文字列をSSLパラメーターで更新します。このファンクションは接続文字列全体を置き換えるため、新しいSSLパラメータと並んで既存のすべてのパラメータを含めます。変更するノードを含む、グループ内のすべてのノードで実行します。例

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
);
  1. 各ノードのpg_hba.conf にエントリを追加して、ノード間接続を許可します。

hostssl all         pgd_replication <node_subnet>/24 cert
hostssl replication pgd_replication <node_subnet>/24 cert

<node_subnet> を、PGDノードの実際のサブネットまたはIP範囲に置き換えます。

  1. 各ノードでPostgresをリロードして、pg_hba.conf の変更を適用します。

pg_ctl reload -D "$PGDATA"

SCRAM-SHA-256での認証とCA検証#

クライアント証明書が使用できない場合は、パスワード認証を使用しながら、接続を暗号化し、CAに対してサーバーの証明書を検証します。

証明書と資格情報のプロビジョニング#

各ノードに以下が設定されていることを確認します。

  • データディレクトリのserver.crt およびserver.key — ノードのサーバー証明書とプライベートキー。それらを生成するためのガイダンスについては、PostgreSQLドキュメントの

SSL certificate setup を参照してください。

  • データディレクトリのroot.crt — サーバーのSSL証明書の検証に使用されるCA証明書。

  • Postgresプロセスユーザーのホームディレクトリにある

.pgpass ファイル、各ノードの正しいパスワードが含まれています。ファイルには、0600

以上の権限が必要です。アクセス許可がオープンすぎる場合、ファイルはサイレントに無視されます。

SCRAM-SHA-256認証の構成#

  1. 各ノードのpostgresql.conf でSSLを有効にします。

ssl = on
ssl_cert_file = server.crt
ssl_key_file = server.key

各ノードでPostgresを再起動して、変更を適用します。

pg_ctl restart -D "$PGDATA"
  1. Node management interfaces を使用して、各ノードの接続文字列を更新します。このファンクションは接続文字列全体を置き換えるため、新しいSSLパラメータと並んで既存のすべてのパラメータを含めます。変更するノードを含む、グループ内のすべてのノードで実行します。

SELECT bdr.alter_node_interface(
  node-1,
  host=host-1 port=5432 dbname=pgddb user=pgd_replication sslmode=verify-ca sslrootcert=root.crt
);
  1. ノード間接続用に各ノードのpg_hba.conf にエントリを追加します。

hostssl all         pgd_replication <node_subnet>/24 scram-sha-256
hostssl replication pgd_replication <node_subnet>/24 scram-sha-256

<node_subnet> を、PGDノードの実際のサブネットまたはIP範囲に置き換えます。

  1. 各ノードでPostgresをリロードして、pg_hba.conf の変更を適用します。

pg_ctl reload -D "$PGDATA"

構成の検証#

SSLの構成後、レプリケーション接続が暗号化され、すべてのノードがアクティブであることを確認します。クラスター内の任意のノードでこれらのクエリを実行します。

  • レプリケーション接続がSSLを使用していることを確認します。

SELECT pid, ssl, version, cipher, bits
FROM pg_stat_ssl
JOIN pg_stat_replication USING (pid);
__OUTPUT__
pid | 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)

成功した結果は、ssl がt に設定された場合、レプリケーション接続ごとに1行を表示します。この出力は、暗号化がアクティブであることを確認しますが、使用されている認証方法は表示されません。

  • pg_hba.conf で設定された認証方法の確認

SELECT type, database, user_name, address, auth_method
FROM pg_hba_file_rules
WHERE auth_method IN (cert, scram-sha-256);
__OUTPUT__
type   |   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)

追加した行は、設定したauth_method たとえば cert またはscram-sha-256 とともに表示されます。

  • すべてのノードがまだ正常に複製していることを確認します。

SELECT node_name, peer_state_name, peer_target_state_name
FROM bdr.node_summary;
__OUTPUT__
node_name | peer_state_name | peer_target_state_name
-----------+-----------------+------------------------
node-1    | ACTIVE          | ACTIVE
node-3    | ACTIVE          | ACTIVE
node-2    | ACTIVE          | ACTIVE
(3 rows)

すべてのノードは、両方の状態列にACTIVE として表示されます。