2026年10月12日
2026年10月12日
PostgreSQLのpg_hba.conf設定方法:接続許可と認証方式の書き方
PostgreSQL に「どこから・誰が・どのDBに・どの方式で」接続してよいかを決めるのが pg_hba.conf です。この記事では、ファイルの場所の調べ方、1行ずつの書き方、scram-sha-256 を使った安全な設定例、反映と確認の手順、よく出るエラーの読み方までを順に説明します。読み終えるころには、リモート接続を必要な範囲だけ許可し、つながらないときに原因を切り分けられるようになります。
なお、WordPress のコアは MySQL / MariaDB を前提としており、PostgreSQL は公式にはサポートされていません。この記事は、WordPress と同じサーバーやネットワークで別のアプリケーション用に PostgreSQL を運用している場合を想定しています。
pg_hba.conf の役割と、postgresql.conf との分担
接続が成立するまでには2段階あります。まず postgresql.conf の listen_addresses で、サーバーがどのネットワークインターフェースで待ち受けるかが決まります。既定値は多くの環境で localhost なので、ここを変えない限り外部からはそもそも届きません。次に、届いた接続に対して pg_hba.conf が「この接続を受け付けるか、どの方式で認証するか」を判定します。
「リモートからつながらない」ときに pg_hba.conf だけを直しても解決しないのは、この分担のためです。listen_addresses の変更は再起動が必要で、pg_hba.conf の変更は設定の再読み込み(reload)で反映される、という違いも覚えておくと作業の段取りが立てやすくなります。
ファイルの場所を確認する
パッケージやディストリビューションによって置き場所が異なるため、推測せずにサーバー自身に聞くのが確実な方法です。
sudo -u postgres psql -c "SHOW hba_file;"
Ubuntu / Debian のパッケージでは /etc/postgresql/<バージョン>/main/pg_hba.conf、RHEL 系の公式パッケージではデータディレクトリ配下(例: /var/lib/pgsql/<バージョン>/data/pg_hba.conf)にあることが多いです。編集前にはコピーを取っておきます。
sudo cp /etc/postgresql/16/main/pg_hba.conf /etc/postgresql/16/main/pg_hba.conf.bak
パスのバージョン番号は例です。SHOW hba_file; の結果に合わせてください。
1行の書式と各項目の意味
pg_hba.conf は1行が1ルールで、基本形は次のとおりです。
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host appdb appuser 10.0.1.0/24 scram-sha-256
hostssl appdb appuser 203.0.113.50/32 scram-sha-256
- TYPE:
localは Unix ドメインソケット経由の接続、hostは TCP/IP(SSL の有無を問わない)、hostsslは SSL 接続のみ、hostnosslは非SSL接続のみに当てはまります。 - DATABASE: データベース名。
allで全DB、replicationはストリーミングレプリケーション用の接続を指す特別なキーワードです(データベース名が replication のDBという意味ではありません)。 - USER: ロール名。
allで全ロール、+グループ名でそのロールのメンバー全員を指定できます。 - ADDRESS: 接続元。
10.0.1.0/24のような CIDR 表記が基本です。単一ホストなら/32(IPv6 なら/128)を付けます。 - METHOD: 認証方式。後述します。
複数のDBやユーザーはカンマ区切りで並べられます。新しいメジャーバージョンでは正規表現での指定や他ファイルの include も使えるようになっていますが、使えるかどうかは手元のバージョンのマニュアルで確認してください(2026年10月現在)。
上から順に評価され、最初に一致した行だけが使われる
ここが最大のつまずきどころです。PostgreSQL は接続のたびに上から順に行を見て、TYPE・DATABASE・USER・ADDRESS が一致した最初の1行の方式で認証します。その行で認証に失敗しても、下の行は試されません。
たとえば先頭付近に host all all 0.0.0.0/0 reject を置くと、その下にどれだけ許可ルールを書いても TCP 接続はすべて拒否されます。具体的なルール(特定DB・特定ユーザー・狭いアドレス)を上に、広いルールを下に書くのが基本です。
認証方式の選び方
主な方式は次のとおりです。
- scram-sha-256: パスワード認証の推奨方式。パスワードそのものをネットワークに流さずに検証します。リモート接続はこれを基本にします。
- md5: 旧来のパスワード方式。互換性のために残っていますが、MD5 パスワードは新しいバージョンで非推奨扱いになっており、新規に使う理由はありません。
- peer:
local接続専用。OS のユーザー名と DB ロール名が一致すれば通します。sudo -u postgres psqlが通るのはこの方式のおかげです。 - trust: 無条件で通します。検証用の一時利用以外では使わないでください。
- reject: 無条件で拒否します。特定の範囲だけを明示的に締め出すときに使います。
- cert: SSL クライアント証明書で認証します。
hostssl行でのみ使えます。
PostgreSQL 14 以降は password_encryption の既定値が scram-sha-256 です。古いバージョンから移行したサーバーでは、ロールのパスワードが MD5 形式のまま保存されていることがあり、その場合に方式だけ scram-sha-256 に変えるとログインできなくなります。次の手順で、先にパスワードを SCRAM 形式で設定し直してください。
-- 保存形式を確認(SCRAM-SHA-256$ で始まれば SCRAM 形式)
SELECT rolname, left(rolpassword, 14) FROM pg_authid WHERE rolcanlogin;
-- SCRAM 形式で保存し直す(psql の \password ならパスワードがログや履歴に残りにくい)
SET password_encryption = 'scram-sha-256';
\password appuser
ALTER ROLE ... PASSWORD '...' を直接打つと、平文のパスワードがシェルの履歴やサーバーログに残る場合があります。対話的に入力できる \password を使うほうが安全です。
設定例:アプリサーバーからだけ接続を許可する
アプリケーションサーバー(10.0.1.0/24)から appdb に appuser で接続させ、それ以外のネットワークからは拒否する例です。
# ローカル管理用
local all postgres peer
local all all peer
# アプリサーバーからの接続(SSL を要求)
hostssl appdb appuser 10.0.1.0/24 scram-sha-256
# レプリカからのレプリケーション接続
hostssl replication replicator 10.0.2.11/32 scram-sha-256
# 上記以外の TCP 接続は拒否
host all all 0.0.0.0/0 reject
host all all ::/0 reject
hostssl を使うにはサーバー側で ssl = on と証明書の設定が済んでいる必要があります。SSL をまだ設定していない場合は、一時的に host で動作確認し、SSL 設定後に hostssl へ切り替える段取りにすると切り分けが楽です。
あわせて、OS やクラウドのファイアウォールでも 5432 番ポートを接続元のアドレスだけに開けておきます。pg_hba.conf の reject は最後の砦であり、ポートをインターネット全体に公開してよい理由にはなりません。
反映と確認
pg_hba.conf は再読み込みで反映されます。再起動は不要です。
sudo -u postgres psql -c "SELECT pg_reload_conf();"
# または
sudo systemctl reload postgresql
ファイルに書式の誤りがあると、再読み込みしても新しい内容は採用されず、ログにエラーが出たまま以前のルールで動き続けます。変更が効いていないことに気付きにくいため、反映前後に pg_hba_file_rules ビューで解釈結果を確認する習慣を付けると安心です。
SELECT line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules;
error 列に値が入っている行が、読み込めなかった行です。このビューはファイルの現在の内容を読むので、reload する前に確認すれば、誤った設定を反映せずに済みます。
最後に、実際の接続元から接続テストをします。
psql "host=10.0.0.5 dbname=appdb user=appuser sslmode=require" -c "SELECT current_user, inet_client_addr();"
よく出るエラーと原因の調べ方
接続エラーはクライアント側にもサーバーログにも出ます。サーバーログには詳細が出るので、まずログを確認します。postgresql.conf で log_connections = on にしておくと、どの接続が来たかを追いやすくなります。
**no pg_hba.conf entry for host "…", user "…", database "…"**一致する行が1つもありません。メッセージに出ている接続元アドレス・ユーザー・DB名・SSLの有無を、そのまま行の条件と見比べます。よくある原因は、アプリが NAT やプロキシ経由で別のアドレスから来ている、hostssl 行しかないのに非SSLで接続している、DB名やロール名の綴り違い、の順です。
**password authentication failed for user "…"**行には一致したが、パスワードが合いません。パスワードの誤りのほか、前述の MD5 形式で保存されたパスワードと scram-sha-256 の組み合わせを疑います。ロールに LOGIN 属性があるかも確認します。
**Peer authentication failed for user "…"**local 接続で peer が使われ、OS ユーザー名とロール名が一致していません。アプリから Unix ソケットでパスワード接続したいなら、そのユーザー用の local 行を scram-sha-256 にするか、-h 127.0.0.1 を付けて TCP で接続し host 行に当てます。
**接続自体がタイムアウトする、Connection refused になる**pg_hba.conf まで届いていません。listen_addresses、ファイアウォール、PostgreSQL が起動しているか(ss -ltnp | grep 5432)を確認します。
作業時の注意
pg_hba.conf の書き換えで管理者自身が締め出されることがあります。local all postgres peer の行は残したまま作業し、SSH でサーバーに入れる状態を確保してから変更してください。本番に適用する前に、同じバージョンのステージング環境で同じ行を試すのが安全です。
まとめ
listen_addressesが「待ち受け」、pg_hba.confが「受け付けと認証方式」を決める。前者は再起動、後者は reload で反映される。- ルールは上から評価され、最初に一致した1行だけが使われる。具体的な行を上、広い拒否を下に置く。
- リモート接続は
scram-sha-256、可能ならhostsslで。trustは検証時の一時利用に限る。 - 反映前に
pg_hba_file_rulesのerror列を確認し、エラー時はサーバーログのメッセージを行の条件と照らし合わせる。