問題の発生
最近、Node.jsバックエンドを新規の Postgres 15 インスタンスに接続しようとした際、行き詰まってしまいました。ローカル接続は完璧に動作していましたが、アプリサーバー(IP 1.2.3.4)をデータベースに向けた途端、接続が拒否されました。
PostgreSQLは設計上、厳格にロックダウンされています。IPアドレス、ユーザー、および対象のデータベースを明示的にホワイトリストに登録しない限り、外部ネットワークからの接続はすべて拒否されます。これらのルールが設定されていない場合、サーバーはハンドシェイクを拒否し、FATALエラーをスローします。
エラーメッセージ
FATAL: no pg_hba.conf entry for host "1.2.3.4", user "admin", database "prod_db", SSL off
エラーの原因
このエラーは通常、次の2つの設定ステップが不足していることに起因します。
- ドアが施錠されている: デフォルトでは、Postgres は
localhost(127.0.0.1) のみをリッスンします。サーバーのパブリックIPやプライベートネットワークインターフェースに届くトラフィックには反応しません。 - セキュリティガードが厳格である:
pg_hba.confファイルは、データベースレベルのファイアウォールとして機能します。クライアントのIPがこのファイルのエントリと一致しない場合、Postgres は即座に接続を切断します。
ステップ1:リスナーを開放する
まず、データベースが実際にネットワークトラフィックを待ち受けていることを確認します。メインの設定ファイルを微調整する必要があります。
postgresql.conf ファイルを探します。Ubuntu の場合は /etc/postgresql/15/main/postgresql.conf を確認してください。Docker を使用している場合、このファイルは通常、マップされたデータボリューム内にあります。
sudo nano /etc/postgresql/15/main/postgresql.conf
listen_addresses 設定を探します。おそらくコメントアウトされているか、'localhost' に設定されています。これをすべてのインターフェースでリッスンするように変更します。
# サーバーがすべてのネットワークインターフェースでリッスンできるようにする
listen_addresses = '*'
注:セキュリティをより強化したい場合は、'' をサーバーの特定のプライベートIPアドレスに置き換えることができます。*
ステップ2:クライアントIPを承認する
次に、IP 1.2.3.4 がユーザー admin として prod_db データベースにログインする権限を持っていることを Postgres に伝えます。
同じディレクトリにある HBA(ホストベース認証)ファイルを開きます。
sudo nano /etc/postgresql/15/main/pg_hba.conf
一番下に新しい行を追加します。構文は TYPE DATABASE USER ADDRESS METHOD というパターンに従います。
# 特定のアプリケーションサーバーのIPを許可する
host prod_db admin 1.2.3.4/32 scram-sha-256
# または、プライベートサブネット全体を許可する(例:10.0.0.0 ~ 10.0.0.255)
host prod_db admin 10.0.0.0/24 scram-sha-256
どの認証方式を使用すべきか?
scram-sha-256: Postgres 13 以降の最新標準です。これを使用してください。md5: 古い構成(Postgres 12 以下)で一般的です。trust: 本番環境では避けてください。 パスワードなしで誰でもアクセスできてしまいます。
ステップ3:設定を再読み込みする
設定の変更は、サービスに通知するまで反映されません。ダウンタイムを避けるために、必ずしもフル再起動が必要なわけではありません。
ターミナルから以下を実行してサービスを再起動します。
sudo systemctl restart postgresql
あるいは、すでに psql セッション内にいる場合は、現在のユーザーを強制終了させることなく設定を再読み込みできます。
SELECT pg_reload_conf();
接続のテスト
リモートマシン (1.2.3.4) に戻り、接続を試みます。-h フラグを使用してデータベースサーバーのIPを指定します。
psql -h 10.0.0.50 -U admin -d prod_db
パスワードの入力プロンプトが表示されれば成功です。接続がタイムアウト(ハング)する場合は、クラウドのセキュリティグループ(AWS SGなど)やローカルのファイアウォール(UFW)を再確認してください。ポート 5432 がインバウンドトラフィックに対して開放されている必要があります。
本番環境向けのプロのヒント
pg_hba.conf で 0.0.0.0/0 を使いたくなる誘惑に負けないでください。設定は簡単になりますが、データベースがインターネット全体に公開されてしまいます。常に特定の CIDR ブロックにアクセスを絞ってください。
複数のサブネットを持つ複雑な VPC を管理する場合、私は ToolCraft のサブネット計算機 を使用しています。これは、必要以上にホワイトリストを広げすぎないよう、IPの範囲に対して正しい CIDR 表記を素早く取得できる便利な方法です。ブラウザベースでデータがローカルに保持されるため、迅速なネットワーク修正に最適です。
最後に、ログに依然として SSL off と表示され、セキュリティポリシーで暗号化が必要な場合は、TYPE を host から hostssl に変更してください。これにより、認証情報を渡す前に暗号化トンネルの交渉をクライアントに強制します。

