مرکزی مواد پر جائیں
友田 陽大
PostgreSQL operations & reliability
PostgreSQL
セキュリティ
アーキテクチャ設計

PostgreSQL セキュリティ堅牢化(ロール・最小権限・pg_hba.conf・SCRAM・TLS/verify-full・OAuth・v18対応)

PostgreSQL を本番品質で守るセキュリティ堅牢化ガイド。スーパーユーザーで動かさない最小権限ロール設計、GRANT/REVOKEとデフォルト権限、public スキーマの落とし穴(PG15の変更)、監視用の定義済みロール、pg_hba.confの認証設計、SCRAMとMD5非推奨、TLS/sslmode=verify-fullで中間者攻撃を防ぐ方法、PostgreSQL 18のOAuth 2.0認証までを公式ドキュメントに忠実に解説します。

Published
Reading time
10 min read
Author
友田 陽大
شیئر کریں

データベースのセキュリティは「最後に足すもの」ではなく、「最初に設計するもの」です。アプリをスーパーユーザーで動かし、pg_hba.conftrust で開け、TLSを require で済ませている——そのどれもが、情報漏洩への最短経路です。

この記事は、PostgreSQL を本番で守るための堅牢化チェックリストを、公式ドキュメントに忠実に解説します。ロールと最小権限、ネットワーク認証、パスワード方式、暗号化(中間者攻撃対策)まで。発注者が「このDBは安全に作られているか」を判断する材料にもなります。本番運用ガイド §6の深掘りです。

この記事のルール:ロール・権限・認証・暗号化の仕様、PostgreSQL 18 の変更点は PostgreSQL 18 公式ドキュメント(2026年6月時点) に基づきます。行レベルセキュリティ(RLS) によるマルチテナント認可はデータベース・RLS クラスタで詳述しているため、本稿では触れず、ロール・ネットワーク・暗号化に集中します。


1. 最小権限:アプリをスーパーユーザーで動かさない

第一の原則。アプリの実行ロールにスーパーユーザーやテーブル所有者を使わない。公式の警告:

データベーススーパーユーザーは、ログインの権利を除き、すべての権限チェックを迂回する。…これは危険な権限であり、不用意に使うべきではない。スーパーユーザーでない役割で大半の作業を行うのが最善である。

ロールはクラスタ全体(公式:「ロールはデータベースクラスタ全体でグローバル」)で、LOGIN 属性を持つものが「ユーザー」、持たないものが「グループ」として機能します。本番の正解は——アプリ専用の最小権限LOGINロールを作り、必要なDMLだけ与えることです。

-- 1) オブジェクト所有者(マイグレーション用・通常運用では使わない)
CREATE ROLE app_owner NOLOGIN;

-- 2) アプリ実行用の最小権限ロール(必要なDMLだけ。所有者でもスーパーユーザーでもない)
CREATE ROLE app_user LOGIN PASSWORD '***';

-- 3) スキーマと既存テーブルへ、必要な権限だけ付与
GRANT USAGE ON SCHEMA app TO app_user;                  -- スキーマのUSAGEは必須
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA app TO app_user; -- serial/identity を使うなら

-- 4) 将来作られるテーブルにも自動で同じ権限を(重要:付け忘れを防ぐ)
ALTER DEFAULT PRIVILEGES IN SCHEMA app
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;

アプリが乗っ取られても、app_userDROP TABLECREATE ROLE もできなければ、被害は「そのロールが触れるデータ」に封じ込められます。これが最小権限による被害局限です。


2. 権限設計:GRANT、デフォルト権限、public スキーマの罠

所有者・PUBLIC・USAGE

公式:「オブジェクトの所有者は、本質的に全権限を持つ」。新規オブジェクトは作成者が所有し全権限を持ちます。他ロールには GRANT必要な分だけ渡します。

特別な擬似ロール PUBLIC は「全ロール」を意味します。公式:「テーブル・列・シーケンス・スキーマ等に対し、PUBLIC には既定で権限が与えられない」。重要なのは、テーブル権限だけでなくスキーマの USAGE も必要な点——両方揃って初めてアクセスできます。

⚠ public スキーマの落とし穴(PostgreSQL 15 の変更)

歴史的な地雷です。公式:

PostgreSQL 15 以降、既定の構成はこの使い方を支える。それ以前(または旧版からアップグレードしたDB)では、public スキーマから PUBLIC の CREATE 権限を削除する必要がある(REVOKE CREATE ON SCHEMA public FROM PUBLIC を実行)。

旧来は「全ユーザーが public スキーマにオブジェクトを作れる」状態で、公式は「これは決して安全なパターンではない」と断じています。

-- 旧版からアップグレードしたDBでは必ず実行(PG15+で新規作成したDBは既定で対策済み)
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
-- さらに厳格にするなら、public への接続時USAGEも絞る
-- REVOKE ALL ON SCHEMA public FROM PUBLIC;

監視・分析には定義済みロール

「読み取りだけのアナリスト」「監視エージェント」にスーパーユーザーを渡すのは過剰です。公式の定義済みロールを使います。

ロール権限
pg_read_all_data全テーブル/ビュー/シーケンスのSELECT 相当+全スキーマの USAGE(RLSは迂回しない)
pg_monitor監視ビュー/関数の読み取り(pg_read_all_settingspg_read_all_stats 等を含む)
pg_read_all_statspg_stat_* の閲覧
-- アナリストは読み取り専用ロールで(スーパーユーザー不要)
GRANT pg_read_all_data TO analyst;
-- 監視エージェントは pg_monitor で
GRANT pg_monitor TO monitoring_agent;

3. ネットワーク認証:pg_hba.conf

「誰が・どこから・どのDBに・どの方式で」接続できるかを決めるのが pg_hba.conf。公式の最重要ルール:

最初に一致したレコードが認証に使われる。「フォールスルー」や「バックアップ」はない:あるレコードが選ばれて認証に失敗しても、後続のレコードは考慮されない。一致するレコードがなければアクセスは拒否される。

つまり順序が命で、上から評価して最初の一致で決まります。堅牢化の要点:

# TYPE     DATABASE   USER       ADDRESS          METHOD
# ローカルの管理用ソケットのみ peer(OSユーザーと一致)
local      all        postgres                    peer
# アプリは TLS 必須(hostssl)+ SCRAM + 送信元を限定
hostssl    appdb      app_user   10.0.0.0/24      scram-sha-256
# 上記に一致しない全接続を明示的に拒否(デフォルト拒否)
host       all        all        0.0.0.0/0        reject
  • hostssl を使い、TLS接続でなければ一致させないhost はSSL/非SSLどちらも一致)。
  • 認証は scram-sha-256
  • trust は厳禁——公式:「無条件で接続を許可する。…パスワードも認証も不要で、誰でも任意のユーザーとしてログインできる」。ローカルの信頼できるソケット以外で使ってはいけません。
  • 送信元IP(CIDR)・DB・ユーザーでできる限り絞る

4. パスワード:SCRAM、MD5 は非推奨に

公式:password_encryption の既定は scram-sha-256。SCRAM は「現在提供される中で最も安全」です。一方 MD5 は弱い——公式:「MD5 ハッシュアルゴリズムは、今日では執拗な攻撃に対して安全とは見なされない」。

そして PostgreSQL 18 で MD5 は非推奨になりました(公式リリースノート):

MD5 パスワード認証を非推奨化する。…将来のメジャー版でサポートは削除される。CREATE ROLEALTER ROLE は、MD5 パスワードを設定する際に非推奨警告を出す

-- パスワードは SCRAM で保存される(既定)。MD5 ロールが残っていれば SCRAM へ移行
SET password_encryption = 'scram-sha-256';   -- 既定
ALTER ROLE app_user PASSWORD '***';          -- 設定し直すと SCRAM ハッシュで保存される

-- MD5 のまま残っているロールを洗い出す
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%';

5. 暗号化:sslmode=verify-full で中間者攻撃を防ぐ

通信の暗号化はサーバー設定とクライアント設定の両輪です。サーバーは ssl = on で有効化(server.crt/server.key が必要)。

決定的に重要なのはクライアントの sslmode です。公式の表が示すとおり、暗号化となりすまし(中間者攻撃)防止は別物。

sslmode盗聴防止中間者攻撃(MITM)防止何を検証するか
require暗号化のみ。証明書を検証しない
verify-caCA次第証明書チェーンをルートCAまで検証
verify-full上記+ホスト名が証明書と一致するか検証

公式:「第三者が通信途中でデータを改変できれば、サーバーになりすませる。SSL は証明書検証でこれを防ぐ」。require は暗号化するだけでなりすましを防げません。本番のクライアントは verify-full +ルートCAで接続します。

# アプリの接続文字列:verify-full でなりすましを防ぐ(require では不十分)
DATABASE_URL="postgresql://app_user@db.internal/appdb?sslmode=verify-full&sslrootcert=/etc/ssl/certs/db-ca.pem"
// node-postgres でも明示的に検証を有効化(rejectUnauthorized を切らない)
import { Pool } from "pg";
export const pool = new Pool({
  connectionString: process.env.DATABASE_URL, // sslmode=verify-full を含む
  ssl: { rejectUnauthorized: true, ca: process.env.DB_CA_CERT }, // 証明書を必ず検証
});

やってはいけないrejectUnauthorized: falsesslmode=require で「とりあえず動かす」。それは暗号化しているのになりすましを許す、最悪の中途半端です。


6. PostgreSQL 18 のセキュリティ強化

公式リリースノートより。

  • OAuth 2.0 認証pg_hba.confoauth メソッドが追加。サードパーティのIdP(OAuth 2.0)で認可・認証できる。中央集権的なID管理に有用(--with-libcurl ビルドが必要)。
  • MD5 非推奨(§4)。
  • SCRAM パススルー:クライアントのSCRAM認証を postgres_fdw/dblink に引き継げる(use_scram_passthrough)——FDWの資格情報をDBに保存せずに済む。
  • TLSssl_ecdh_curvessl_groups に改名(複数曲線を指定可、既定に X25519 を含む)。OpenSSL 1.1.1 未満はサポート終了
  • 権限系:pg_get_acl()ALTER DEFAULT PRIVILEGES がラージオブジェクト対応、定義済みロール pg_signal_autovacuum_worker 追加。

7. 堅牢化チェックリスト

  1. アプリは最小権限のLOGINロールで動かす(スーパーユーザー・所有者を使わない)。
  2. ALTER DEFAULT PRIVILEGES で将来のテーブルにも正しい権限を自動付与。
  3. 旧版DBは REVOKE CREATE ON SCHEMA public FROM PUBLIC(PG15+の既定に合わせる)。
  4. 読み取り/監視は pg_read_all_data / pg_monitor(スーパーユーザーを配らない)。
  5. pg_hba.confデフォルト拒否、最初の一致が意図どおりの順序、hostsslscram-sha-256、送信元IP/DB/ユーザーで限定、trust 禁止
  6. パスワードは SCRAM。残った MD5 ロールを移行(PG18で非推奨)。
  7. クライアントは sslmode=verify-full +ルートCA(require は不可)。
  8. 余裕があれば OAuth 2.0(PG18)で中央ID管理、OpenSSL ≥ 1.1.1 を担保。
  9. マルチテナントの行単位の分離は RLSデータベース・RLS クラスタ)で。

8. まとめ

  • 最小権限が出発点。アプリをスーパーユーザー・所有者で動かさない。ALTER DEFAULT PRIVILEGES で付け忘れを防ぐ。
  • public スキーマの罠(PG15の変更)に注意——旧版DBは REVOKE CREATE ... FROM PUBLIC
  • pg_hba.conf は最初の一致。デフォルト拒否・hostsslscram-sha-256・送信元限定。trust 厳禁。
  • SCRAM を使い、MD5 を捨てる(PG18で非推奨)。
  • sslmode=verify-full でなりすましを防ぐ(require は暗号化だけで不十分)。
  • PG18 は OAuth 2.0 認証を追加。

これで PostgreSQL の運用・信頼性シリーズは一巡です。本番運用ガイドを起点に、接続プーリングバックアップ/PITRレプリケーション/HA論理レプリケーション/アップグレード無停止DDLと合わせて、「壊さない・止めない・詰まらせない・守る・進化させる」を満たす PostgreSQL を設計してください。


参考(PostgreSQL 18 公式ドキュメント)

友田

友田 陽大

وزیر (METI) ایوارڈ یافتہ پروڈکٹ کے ڈویلپر۔ TypeScript + Python + AWS کے ساتھ میں SaaS، صنعتی ڈیجیٹل تبدیلی اور پروڈکشن کے قابل جنریٹو اے آئی (RAG) تنہا ابتدا سے انتہا تک فراہم کرتا ہوں — تقاضوں کی تعیین سے انفراسٹرکچر اور آپریشن تک۔

Got a challenge?

From design to implementation and operations — solo × generative AI

Implementation like this article's, end to end from requirements to production. Start with a free 30-minute technical consult and tell me about your situation.

پروجیکٹ کی بنیاد پر کام اور تکنیکی مشاورت دونوں کے لیے دستیاب ہوں۔ 30 منٹ کی مفت مشاورت سے آغاز کریں۔

最短ルート:カレンダーから直接予約

相談内容が固まっている方は、フォーム送信よりその場で日程を確定する方がスムーズです。下記から空き時間をお選びください。

  • 30分のオンライン無料相談
  • Google Meet / Zoom / Microsoft Teams
  • NDA 商談前締結可・無理な営業はいたしません
無料相談の空き枠を予約する

یہ بھی پڑھنے کے قابل