変更要約: 初版(主題G1・G1.1〜G1.4)
1.1データベースサーバ構築
サーバ構築時に固める暗号化・認証・監査の基盤を深掘りします。SSL通信とpgcryptoによるデータ暗号化、暗号化状況を確認するpg_stat_ssl、クライアント認証のSCRAM-SHA-256、監査ログの中核log_statementと稼働統計の設定track_functions・track_activities、ユーザー/DB単位でパラメータを固定するALTER ROLE・ALTER DATABASE、チェックサム付きで初期化するinitdb --data-checksums、クラスタ内の主要ディレクトリpg_tblspc・pg_wal・pg_stat_tmpを押さえます。
Silver で学んだ「動く」構築から、Gold では「監査に耐え、暗号化され、改ざんを検知できる」構築へと視点が上がります。本番運用のサーバは、通信経路の暗号化、パスワードの安全な検証方式、誰が何をしたかを追える監査ログ、そしてディスク破損を早期に検知するチェックサムが揃って初めて「構築完了」と言えます。この節ではその4本柱を、実際にサーバを固める順序で見ていきます。
1.1.1SSL通信とデータ暗号化
- SSL=クライアント-サーバ間の通信路を暗号化する仕組み。
postgresql.confのssl = onで有効化し、サーバ証明書・秘密鍵(ssl_cert_file/ssl_key_file)を用意する。pg_hba.confのhostssl行で SSL 接続のみ許可する運用も可能。 - pgcrypto=拡張機能(
CREATE EXTENSION pgcrypto)。通信経路ではなく保存データそのものを暗号化する用途で、crypt()(パスワードハッシュ)・pgp_sym_encrypt()/pgp_sym_decrypt()(対称鍵暗号)などの関数を提供する。SSL がカバーしない「保存データの暗号化」を補う。 - pg_stat_ssl=各バックエンドの SSL 接続状況(使用有無・プロトコルバージョン・暗号スイート)を確認するシステムビュー。
pidでpg_stat_activityと結合すれば「どのセッションが SSL 化されているか」を監査できる。
1.1.2クライアント認証と監査ログ
- SCRAM-SHA-256=
pg_hba.confで選べる認証方式の中で最も安全なパスワード認証。md5はハッシュがカタログに残り再生攻撃に弱い面があるが、SCRAM-SHA-256 はチャレンジ・レスポンス方式でパスワード自体を送受信しない。新規構築では既定 (password_encryption = scram-sha-256) として採用する。 - 監査ログの中核は log_statement(
none/ddl/mod/all。実行された SQL 文自体をログに記録する範囲)。track_functions(PL/pgSQL 関数呼び出しの統計をpg_stat_user_functionsに集計するか)と track_activities(現在実行中のクエリをpg_stat_activityに反映するか)は監査ログではなく稼働統計・監視の設定で、log_statement と区別する。 - ALTER ROLE・ALTER DATABASE=ユーザー単位/データベース単位で
SETパラメータを固定する。例:ALTER ROLE app_user SET statement_timeout = '30s'のように、特定ロールにだけ挙動を強制できる。監査要件で「このユーザーは必ず全文ログを取る」ならALTER ROLE audit_user SET log_statement = 'all'のように使う。
「通信路の暗号化=SSL・保存データの暗号化=pgcrypto」「最も安全なパスワード認証=SCRAM-SHA-256(md5より上位)」「ユーザー/DB単位のパラメータ固定=ALTER ROLE/ALTER DATABASE」 の切り分けが最頻出です。log_statement(監査ログ)と track_functions/track_activities(稼働統計)は役割が異なる(SQL文自体/関数呼び出し統計/実行中クエリ)ことも定番で、track_* を「監査ログ」と混同しない点が問われます。
新規サーバ構築の実務フローを追いましょう。まず initdb --data-checksums でクラスタを初期化します。これはinitdb の実行後には有効化できない構築時にしか選べないオプションで、以後すべてのページにチェックサムが付き、ディスクの物理破損(ビット化け)を読み取り時に検知できるようになります。次に postgresql.conf で ssl = on にしてサーバ証明書を配置し、pg_hba.conf の各行で認証方式を scram-sha-256 に統一します(既存 md5 行が残っていれば置き換え)。監査要件があれば log_statement = 'mod'(更新系のみ記録)や track_functions = pl(PL 言語の関数のみ集計)のように用途に応じて絞り込み、特定の重要ロールにだけ ALTER ROLE finance_admin SET log_statement = 'all' で全文ログを強制します。保存データのうち特に機微な列(例:マイナンバーやクレジットカード番号)は pgcrypto の pgp_sym_encrypt(column, key) で暗号化して格納し、参照時に pgp_sym_decrypt() で復号します。構築後、実際に SSL が効いているかは SELECT pid, ssl, version, cipher FROM pg_stat_ssl JOIN pg_stat_activity USING (pid); のようなクエリで確認します。クラスタのディレクトリ構造も把握しておく必要があります。pg_tblspc はテーブルスペースへのシンボリックリンクが置かれるディレクトリ、pg_wal(旧称 pg_xlog)は WAL セグメントファイルが置かれるディレクトリ、pg_stat_tmp は統計情報の一時ファイルが置かれるディレクトリで、stats_temp_directory パラメータで場所を変更できます(tmpfs に置いてディスク I/O を削減する運用もある)。
| 項目 | 役割 | 要点 |
|---|---|---|
| SSL | 通信路の暗号化 | ssl=on・hostssl行で強制可 |
| pgcrypto | 保存データの暗号化 | pgp_sym_encrypt/decrypt・crypt() |
| SCRAM-SHA-256 | パスワード認証 | md5よりチャレンジレスポンスで安全 |
| initdb --data-checksums | ページチェックサム | 構築時のみ選択可・後から有効化不可 |
ひっかけ: 「pgcrypto を使えば SSL は不要になる」は誤りです。pgcrypto は保存データの暗号化、SSL は通信路の暗号化で目的が異なり、両者は補完関係にあります。また「initdb 実行後に ALTER SYSTEM でチェックサムを有効化できる」も誤り=data_checksums は initdb 時にのみ決定され、既存クラスタで有効化するには pg_checksums --enable(オフライン)などクラスタ再構築に近い操作が必要です(本ノートの範囲では initdb 時点の理解を優先)。
1.1.3この節のまとめ
- SSL=通信路暗号化/pgcrypto=保存データ暗号化。pg_stat_ssl で暗号化状況を確認。認証はSCRAM-SHA-256が最も安全
- 監査ログ=log_statement(SQL文)/稼働統計=track_functions(関数統計)・track_activities(実行中クエリ)(track_* は監査ログではない)。ALTER ROLE/DATABASEでユーザー/DB単位に固定
- initdb --data-checksums は構築時のみ選択可。クラスタ内はpg_tblspc(テーブルスペースリンク)・pg_wal(WAL)・pg_stat_tmp(統計一時ファイル)
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. 新規にデータベースクラスタを構築する。将来のディスク破損を早期検知できるようにしたい。initdb 実行時に指定すべきオプションはどれ?
Q2. 特定の管理者ロールについてのみ、実行されたすべてのSQL文を必ずログに残したい。適切な設定方法はどれ?
Q3. テーブル内の特定カラム(保存データ)を暗号化して格納したい。この目的に最も適した拡張機能はどれ?

