5432
PostgreSQL のクラスタが待ち受けるポート。psql に断られたときの原因は、ループバック限定か、二つ目のクラスタが占有しているか、pg_hba.conf に止められているかのどれかです。
自分の環境の行をそのまま実行してください。ポートを掴んでいるプロセス名と、バインドしているアドレスが出ます。たいていはそれだけで答えが分かります。
sudo lsof -nP -iTCP:5432 -sTCP:LISTEN`-n` でアドレスを数値のまま、`-P` で 5432 がサービス名にならないようにするので、NAME の列が読みやすく保たれます。`-iTCP:5432` でポートを選び、`-sTCP:LISTEN` でリスナーだけを残します。COMMAND はたいてい `postgres`、PID が手を出す番号、USER が動いているアカウント、NAME がバインド先です。`127.0.0.1:5432` は `listen_addresses = 'localhost'` の既定そのもので、他のマシンから接続できない理由がまさにこれ。`*:5432` は全インターフェイスです。何も出ず lsof が終了コード 1 で終われば誰も待ち受けていません。`sudo` なしでは自分のプロセスしか見えないので、Postgres.app のインスタンスや他ユーザーが公開している Docker のポートは空きポートに見えます。COMMAND の列に `com.docker.backend` とあればコンテナが持ち主なので、プロセスではなくコンテナを止めてください。
sudo ss -tlnp 'sport = :5432'`-t` で TCP ソケット、`-l` で待ち受けのみ、`-n` でサービス名の解決を飛ばし、`-p` で各ソケットを使っているプロセスを出し、`sport = :5432` で送信元ポートを絞ります。何よりも先に Local Address:Port の列を読んでください。`127.0.0.1:5432` は素の `listen_addresses` の既定、`0.0.0.0:5432` は誰かが `*` か実アドレスを設定した状態、`[::]:5432` は IPv6 のワイルドカードです。持ち主は `users:(("postgres",pid=1123,fd=6))` と出ます。クラスタが複数入っているなら、フィルタを `'sport >= :5432 and sport <= :5435'` に広げてください。5433 にいる二つ目のクラスタは、ここで最もよくある不意打ちです。net-tools 版の `sudo netstat -tlnp | grep :543` も、スラッシュ区切りの pid/program の列で同じ仕事をします。どちらも自分の所有でないプロセスを名指しするには特権が必要です。
netstat -ano | findstr ":5432"`-a` ですべての接続と待ち受けているポートを表示し、`-n` でアドレスとポートを数値で表現し、`-o` で所有プロセス ID を最後の列に含めます。欲しい行は State が LISTENING のもの。Local Address が `127.0.0.1:5432` なのか `0.0.0.0:5432` なのかが、このマシンでしか使えないサーバーとネットワークから使えるサーバーの違いです。PID は `tasklist /FI "PID eq 4212"` で引けます。この PID フィルタは eq・ne・gt・lt・ge・le を受け付け、出てくるのはたいてい `postgres.exe` です。`findstr` は部分一致なので、その列が本当に Local Address で、本当に 5432 で終わっているかを確かめてから動いてください。
Get-NetTCPConnection -LocalPort 5432 | Select-Object LocalAddress,LocalPort,State,OwningProcess部分一致ではなくポートを厳密に一致させるので、近い番号に複数のクラスタが入っている環境ではこちらのほうが安全です。`LocalAddress` が `127.0.0.1` で `State` が `Listen` ならループバック限定、`0.0.0.0` や `::` ならネットワーク全体です。`OwningProcess` を `Get-Process -Id` に渡せばイメージ名が分かります。結果が空なのに起動が失敗するなら、占有ではなく予約です。`netsh interface ipv4 show excludedportrange protocol=tcp` が Hyper-V・WSL2・Docker Desktop が起動時に確保する範囲を一覧しますが、そこに入ったポートにはプロセスが出てくることは決してありません。
`nmap -Pn -p 5432 db.example.com` は、クライアントが実際にいる場所から届くかどうかを確かめます。`-Pn` はホスト探索を飛ばすので、ping を落とすホストもスキャンされます。三つの状態には正確な意味があります。`open` は対象上のアプリケーションがそのポートで待ち受けている、`closed` はホストは答えたが誰も待ち受けていない、`filtered` はファイアウォールやフィルタ、その他のネットワーク上の障害物がプローブを塞いでいて nmap にはどちらか判断できない、です。PostgreSQL では `closed` はほぼ必ず `listen_addresses` が `localhost` のままという意味で、サーバーは完璧に動いていて、単にそのインターフェイスにいないだけ。`filtered` ならセキュリティグループかホストのファイアウォールがパケットを捨てています。`--reason` でどのパケットが決め手になったかが分かり、`-sV` でサービスの識別を頼めます。スキャンは自分が責任を持つホストにだけ。
| 出ているもの | 意味 |
|---|---|
psql: error: connection to server at "db.example.com" (203.0.113.9), port 5432 failed: Connection refused — Is the server running on that host and accepting TCP/IP connections? | libpq がこのヒントを出すのはカーネルが接続を拒否したときだけで、そして重要なのは問いの後半です。ホストは生きていてリセットを返したので、これがファイアウォールであることはほぼありません。クラスタが停止しているか、`listen_addresses = 'localhost'` のまま動いていてあなたが叩いたインターフェイスにいないかのどちらかです。データベースのホストでコマンドを実行してバインドアドレスを読んでください。`127.0.0.1` と出たなら、ファイアウォールをどれだけいじっても解決しません。 |
psql: error: connection to server at "db.example.com" (203.0.113.9), port 5432 failed: Connection timed out | 何も答えていません。拒否のメッセージとは違い、こちらがパケットフィルタのケースです。クラウドのセキュリティグループ、ホスト上のファイアウォール、ネットワーク ACL が、SYN を拒否ではなく破棄しています。拒否は即座に返り、破棄は接続タイムアウトいっぱいかかるので、待ち時間そのものが信号です。`nmap --reason` はここでは `filtered`、上の拒否のケースでは `closed` を返します。 |
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory — Is the server running locally and accepting connections on that socket? | ポートは最初から関係していません。`host` が空か絶対パスに見えたので libpq は Unix ドメインソケットのパスを取り、そこにソケットファイルがなかっただけです。たいていはサーバーがコンテナの中にあるか、クライアントが `/tmp` を前提にビルドされているのにパッケージ版のサーバーが `/var/run/postgresql` にソケットを置いているかです。TCP を強制するなら `-h 127.0.0.1`、そうでなければ `-h` を本当のソケットのディレクトリに向けてください。 |
FATAL: no pg_hba.conf entry for host "10.0.0.5", user "app", database "appdb", no encryption | この一覧で最も good news なメッセージです。ネットワークもポートもサーバーも正常で、PostgreSQL はホストベース認証のルールを読むところまで到達したうえで、一致するものを見つけられませんでした。最後のフィールドに注目してください。暗号化の状態が出るので、`hostssl` を要求するルールに対する `no encryption` がまさにそのずれです。`pg_hba.conf` に行を足すか広げて reload すれば済み、ネットワークには触るところがありません。 |
FATAL: password authentication failed for user "app" | これもポートの問題ではありません。ハンドシェイクは完了し、認証情報が拒否されました。パスワードが違うか、クライアントが満たせない `pg_hba.conf` の方式です。`md5` しか知らない古いドライバは、パスワードが正しくても `scram-sha-256` の行には通りません。兄弟のようなメッセージ `FATAL: Peer authentication failed for user "app"` は、ネットワーク障害の正反対を意味します。Unix ソケットから入ってきたので、PostgreSQL は OS 上のユーザー名とデータベースのロールを突き合わせています。 |
LOG: could not bind IPv4 address "0.0.0.0": Address already in use — HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. | サーバー自身の言葉で書かれた `EADDRINUSE` で、ヒントもちゃんと仕事をしています。本当に postmaster が動いているなら、自分の環境のコマンドで見つけてください。謎の何かではなく二つ目のクラスタであることがほとんどです。何も待ち受けていないなら、前のサーバーが `TIME_WAIT` のソケットを残しただけで、ポートはまもなく空きます。待つのが正解ですし、新しいクラスタを 5433 で起動するのも正解です。 |
could not bind IPv4 address: Permission denied | 特権ポートの話ではありません。あれは 1024 未満だけです。Linux ホストでは、SELinux か AppArmor がそのバイナリの bind を拒んでいるのが普通で、PostgreSQL をポリシーがラベル付けしていない非標準のポートに移した直後によく起きます。あるいは必要な capability なしで起動したコンテナです。ファイアウォールではなく監査ログを見てください。Windows では同じ形が、そのポートが予約された除外範囲に入っている、つまり探すべき所有プロセスがそもそも存在しない、という意味になります。 |
The application connects but reads stale data, or a table it just created is missing | 1 つ違いのポートに 2 つのクラスタがいます。その場でアップグレードしたマシンは、旧メジャーバージョンを 5432、新しいほうを 5433 で動かしていることが多く、ポートを省いた接続文字列は黙って 5432 を取ります。レプリケーションが壊れたと決めつける前に、`SHOW port;` と `SHOW server_version;` でそのセッションがどちらにいるのか聞いてください。 |
IANA は 5432 を TCP・UDP 両方で `postgresql` として登録していますが、PostgreSQL が使うのは TCP だけです。番号については公式ドキュメントも素っ気なく、サーバーが待ち受ける TCP ポートは既定で 5432 だと書いてあるだけ。ただし本当の権威は動いているサーバーで、聞き方は `SHOW port;` です。これは聞こえる以上に重要で、メジャーバージョンを 2 つ入れたマシンでは二つ目のクラスタが 5433 にいるのが普通なので、間違ったデータベースを見ているように思える `psql` のセッションは、たいてい正しいポートで間違ったクラスタを見ています。誰が届くかを決めるのは、その次の二つの既定値です。`listen_addresses` の既定は `localhost` で、ドキュメントはこれをローカルの TCP/IP ループバック接続だけを許す設定だと説明しています。つまり素のサーバーは、人間が設定を変えるまで他のマシンからは届きません。読み込まれていないかもしれない `postgresql.conf` を眺めるより、`SHOW listen_addresses;` でサーバーに聞いてください。それから MySQL と違って、libpq の接続文字列における `localhost` は普通の TCP のホスト名です。libpq が Unix ドメインソケットに切り替えるのは `host` が空か絶対パスに見えるときだけで、その場合の値はソケットファイルの置かれたディレクトリを指します。上流のビルドなら `/tmp` ですが、パッケージャーはよく別の場所に移します。最後に、ポートに届いただけでは仕事の半分です。TCP のハンドシェイクを終えた接続がその先へ進めるかどうかを、送信元アドレス・ユーザー・データベース単位で決めるのが `pg_hba.conf` で、5432 の問題がネットワークのエラーではなくサーバーのエラーとして出てくることが多いのはこのためです。
5432 をインターネットに出さないでください。上流の既定は既にあなたの味方です。`listen_addresses` は `localhost` なので、インターネットから届く PostgreSQL は誰かが意図的にそうしたものです。そしてそれと一緒に有効化されがちなのが、世界中に一致するほど広い `pg_hba.conf` の行です。ポートが届くようになった瞬間、さらに二つの既定値が効いてきます。`ssl` の既定は `off` なので、有効にしていなければパスワードも結果セットも含めてプロトコルは平文で流れます。そして libpq の `sslmode` の既定は `prefer`、ドキュメントの言葉では「まず SSL 接続を試し、失敗したら非 SSL 接続を試す」——何も検証せず静かにダウングレードする日和見的な暗号化なので、間に入られても気づけません。外からデータベースに届く必要があるなら、SSH でトンネルするか、プライベートサブネットに置くか、ファイアウォールで送信元アドレスを絞ってください。`pg_hba.conf` では `md5` ではなく `scram-sha-256` を必須にし、`trust` はソケット以外では絶対に使わないこと。クライアント側では、`verify-ca` がクライアントに置いたルート証明書までチェーンを検証し、`verify-full` はさらにサーバーのホスト名が証明書の名前と一致することも検証します。中間者に耐えられる組み合わせは、`sslrootcert` を伴う `verify-full` だけです。
どれもブラウザ内で完結します。アップロードは発生しません。
5432 を調べているとき、ついでに確認することになりがちなポートです。
ほぼ権限の問題です。lsof や ss はソケット自体は出しますが、他ユーザーのプロセスは所有者の列を伏せるので、システムアカウントやコンテナランタイム、launchd が起動したサーバーは sudo を付け直すまで持ち主不明のリスナーに見えます。Windows は逆で、netstat には何も出ないのに bind だけ失敗します。これは Hyper-V や WSL2、Docker Desktop が起動時に予約したポート帯に当たっている状態です。
何なのかを先に見てください。取り残された開発サーバーなら問題ありませんが、書き込み中のデータベースは別ですし、他が依存しているシステムサービスも同様です。持ち主がコンテナならコンテナごと停止してください。ホストから見えるプロセスを kill してもランタイムが再起動するだけです。どうしても止められないものなら、自分のサービスを別のポートへ移すほうが早く片付きます。
0.0.0.0 ではなく 127.0.0.1 にバインドしているからです。各ページのコマンドがプロセス名と並べてバインド先アドレスを出しているのはこのためで、ループバックにバインドしたものはファイアウォールの設定に関係なく自分のマシンからしか届きません。最近は意図的にそれを既定にしているフレームワークも多いので、たいていはバグではなくフラグの問題です。すでに 0.0.0.0 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。
ほとんどなりません。インターネット全体を舐めるスキャナーはポート範囲を丸ごと走査し続けているので、稼げるのは数時間であって安全ではなく、代わりに関係者全員がその番号を覚える羽目になります。既定ポートを狙う無差別スキャンのログが減るという効果は確かにありますが、それだけです。結果を変えるのは認証と、送信元アドレスを絞ったファイアウォールと、そもそも外に出さないことです。
ポート 5432 でまだ詰まっていますか。ポート一覧をすべて見る。あるいは上に戻って、実際に出たエラー文から追ってください。