PostgreSQL で「Peer authentication failed for user」が出て接続できない
peer 認証は OS のユーザー名をそのままデータベースのユーザー名として突き合わせる。
両者が違えばパスワードの正誤に関係なく弾かれる。
OS ユーザーを合わせるか、TCP 接続かパスワード認証へ切り替える。
公開:
要約
peer 認証は、Peer Authentication(新しいタブで開く) が説明するとおり クライアントの OS ユーザー名をカーネルから取得し、それをそのまま許可するデータベースユーザー名として扱う。
パスワードは一切見ない。
だから OS 側で alice としてログインしている限り、myuser としては入れない。
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed:
FATAL: Peer authentication failed for user "myuser"エラーに socket と出ているのが手掛かりで、これは Unix ドメインソケット経由の接続を意味する。
peer はローカル接続でのみ使える方式なので、TCP に切り替えるだけでも別の行が適用される。
よくある原因
- OS ユーザーと DB ユーザーの不一致: Debian / Ubuntu のパッケージは
local all all peerを既定にしている。
自分の OS アカウントのまま-U myuserを指定すれば必ず落ちる。 - パスワードを設定したのに使われない:
ALTER ROLE myuser PASSWORD ...を実行しても、pg_hba.confがpeerのままならパスワードは参照されない。
「パスワードが違う」と誤解しやすい。 - 接続経路の取り違え:
-hを付けないpsqlはソケット接続になる。-h 127.0.0.1を付けるとhost行が使われ、認証方式が変わる。 - ユーザー名マップ未定義: OS ユーザー名と DB ユーザー名を意図的に分けたい場合は
pg_ident.confにマップが要る。
書かないままpeerを使えば一致しない。 - 再読み込み漏れ:
pg_hba.confは起動時と再読み込み時にしか反映されない。
編集しただけでは変わらない。
解決策
1. OS ユーザーを合わせる
sudo -u postgres psql管理作業なら、これが最も手数が少ない。postgres ロールで入ったあと、必要なロールやデータベースを作る。
2. TCP 接続に切り替える
psql -h 127.0.0.1 -p 5432 -U myuser -d mydb-h を付けると pg_hba.conf の host 行が使われる。
アプリケーションからの接続は元々こちらなので、症状が psql でだけ出る場合はこの違いが原因である。
3. パスワード認証に変える
# TYPE DATABASE USER ADDRESS METHOD
local all all scram-sha-256The pg_hba.conf File(新しいタブで開く) が定めるとおり、上から順に最初に一致した行だけが使われる。peer の行が上に残っていると書き換えたつもりでも効かないので、順序も確認する。
4. ユーザー名マップを使う
pg_ident.conf:
# MAPNAME SYSTEM-USERNAME PG-USERNAME
app deploy myuserpg_hba.conf:
local all all peer map=appOS の deploy で myuser として入れるようになる。
パスワードを持たせずに済むので、サーバー上のデプロイ用アカウントに向く。
5. 設定を再読み込みする
sudo systemctl reload postgresqlまたは接続済みのセッションから次を実行する。
SELECT pg_reload_conf();実際に適用された内容は SELECT * FROM pg_hba_file_rules; で確認できる。
構文エラーがあれば error 列に出るので、再読み込みが黙って失敗している場合の切り分けに使える。