テクノロジー・イノベーション

PostgreSQLのREPLICATION権限、複製に必要でも広過ぎる

|著者: QUASA編集チーム|2 分で読めます
PostgreSQLのREPLICATION権限、複製に必要でも広過ぎる

論理レプリケーション用アカウントを最小権限にする基本形は、専用ロールへLOGINとREPLICATIONだけを付け、SUPERUSERとBYPASSRLSを与えず、pg_hba.confで接続元と対象データベースを限定し、初期コピー対象のテーブルにだけSELECTを許可することだ。Publicationの作成・変更やテーブル所有権は、常時接続する複製ロールから管理用ロールへ分離する。

それでもREPLICATION属性自体を特定のPublicationへ限定することはできない。接続可能なSubscriptionは同じデータベース内の別Publicationにもアクセスできるため、行フィルターや列リストだけを機密情報の認可境界にはできない。必要な複製を維持しながらこの広さを抑えるには、ロール、接続経路、SELECT、RLS、資格情報の有効期間を別々の制御点として扱う。

用途ごとに専用ロールを作る

論理レプリケーション、物理レプリケーション、バックアップ、CDC、監視を一つのアカウントへまとめない。それぞれで接続方式、対象データベース、参照する表、利用クライアント、資格情報の保管場所、停止時の影響が異なる。共有アカウントでは、廃止した用途だけを失効させることが難しくなる。

論理レプリケーション専用ロールは、たとえば「CREATE ROLE lr_app WITH LOGIN REPLICATION NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS」のように作る。実際のロール名にはシステムと用途を含め、所有者ロールや書き込み用ロールを継承させない。パスワードをSQL履歴へ残さないよう、対話的な設定手段か組織のシークレット管理基盤から登録する。

論理レプリケーションの公式セキュリティ文書 では、接続ロールにREPLICATIONまたはスーパーユーザー権限、LOGIN、pg_hba.confでの許可が必要で、初期データコピーには公開対象テーブルのSELECTも必要とされる。Publication自体には権限がなく、パブリッシャー側の権限検査は接続開始時に行われ、その後の変更レコードごとには再検査されない。

pg_hba.confは実データベース名と接続元で絞る

承認済み購読ホストから対象データベースへの論理レプリケーション接続だけを許可するpg_hba.confの検証

論理レプリケーションでは、pg_hba.confのdatabase欄に特殊値「replication」ではなく、Publicationがある実データベース名を指定する。「replication」が一致するのは、データベース名を指定しない物理レプリケーション接続であり、論理レプリケーション接続には一致しない。

購読側の固定IPv4アドレスが192.0.2.40、対象データベースがappdb、ロールがlr_appという条件付きの例なら、「hostssl appdb lr_app 192.0.2.40/32 scram-sha-256」とする。これで接続形式、データベース、ロール、単一ホスト、認証方式を一行に限定できる。フェイルオーバー先が必要なら、広いサブネットを許可するのではなく、承認済みアドレスを個別に追加する。

pg_hba.confの公式仕様 が示す通り、認証レコードは上から照合され、最初に一致した一行だけが使用される。変更時はpg_hba_file_rulesのerror列で構文を確認し、再読み込み後の新規接続が想定した規則に一致するかを検証する。データベースのCONNECT権限も個別化する場合は、PUBLICに残るCONNECTを確認する。ただし、その剥奪は他の利用者にも影響するため、独立した変更として評価する。

SELECTは初期コピー対象の表に限定する

REPLICATION属性だけでは、Subscriptionの作成時や新しいテーブルを追加した際の初期データ同期を完了できない。接続ロールには、初期コピーする公開テーブルのSELECTが必要になる。スキーマ全体へ包括的に付与せず、Publicationの対象を確定してから表単位でGRANTし、Publication定義と権限一覧を同じ変更記録へ残すと差分を追いやすい。

初期同期後にSELECTを取り消す設計も可能だが、新規テーブルの追加、再同期、Subscriptionの再作成では再び必要になる。常時保持するなら公開表だけに限定し、都度付与するなら同期手順へGRANTとREVOKEを組み込む。CDC製品が通常のSQL接続でも表を読む場合は、PostgreSQL標準の論理レプリケーションに必要な権限と、製品固有の権限を台帳上で分ける。

Publicationを作成・変更する能力や公開表の所有権は、接続ロールへ加えない。定義を管理するロールと変更ストリームを読むロールを分ければ、接続資格情報が漏れた際に公開範囲そのものを変更される余地を減らせる。複数のツールが同じPublicationを利用する場合も、ツールごとにロールを分ければ、一つを廃止しても他の接続を残せる。

RLSによる部分複製を黙って通さない

RLSが適用された公開表で部分複製を続けず、確認のため論理レプリケーションを停止する動作

接続ロールがSUPERUSERとBYPASSRLSを持たなければ、パブリッシャー側の行レベルセキュリティポリシーが実行され得る。購読側が完全な複製を期待している環境では、ポリシーによって一部の行だけが流れる状態は整合性障害として見つけにくい。

すべてのテーブル所有者を信頼できない場合は、接続文字列に「options=-crow_security=off」を指定できる。これはRLSを迂回する設定ではない。テーブル所有者がRLSポリシーを追加したとき、ポリシーが見せる行だけを複製する代わりに処理を停止させる設定である。採用時は停止を検知する監視と、ポリシーと公開範囲を照合して復旧する担当を決めておく。

Publicationの行フィルターや列リストは複製対象を制御できるが、接続資格情報に対する完全な認可境界ではない。同じデータベースの別Publicationが同じ情報を公開し得るためだ。機密度が大きく異なるデータを強く分離するなら、Publication名だけでなく、データベース、接続ロール、pg_hba.confの許可経路まで分ける。

ローテーションは既存接続の終了まで行う

パスワード認証を使う場合は、クライアント互換性を確認してSCRAM-SHA-256を選ぶ。PostgreSQLのパスワード認証文書 は、SCRAM-SHA-256を現在提供される方式のうち最も安全とし、MD5暗号化パスワードのサポートは非推奨で将来削除されるとしている。Subscription定義、設定ファイル、環境変数、シークレット管理基盤のどこに資格情報があるかを記録し、バックアップや運用ログへの平文混入も点検する。

停止時間を抑えて更新するなら、新しい専用ロールへ同じ最小権限と接続元制限を設定し、購読側の接続情報を切り替える。新しいセッションで複製継続を確認してから、旧ロールをNOLOGINにし、REPLICATION属性と不要なSELECTを取り消す。

ただし、パブリッシャー側の権限は接続開始時に検査され、変更レコードごとには再検査されない。即時失効が必要な事故対応では、ロール属性の変更だけで終えず、そのロールの既存レプリケーション接続を特定して終了させる。切断後に旧資格情報で自動再接続できないことを確認して失効完了とする。

監査はロール、経路、データ、失効を一組にする

設定項目の有無だけではなく、誰が、どこから、どのデータへ、いつまで到達できるかを一組として監査する。定期点検と変更レビューには、少なくとも次の項目を含める。

  • 論理レプリケーション、物理レプリケーション、バックアップ、CDC、監視でロールが分離されている。
  • 接続ロールはLOGINとREPLICATIONを持つが、SUPERUSER、BYPASSRLS、CREATEDB、CREATEROLEを持たない。
  • 不要なロールメンバーシップ、テーブル所有権、Publicationの作成・変更能力がない。
  • pg_hba.confが対象データベース、専用ロール、承認済み接続元、認証方式に限定されている。
  • SELECTが初期同期に必要な公開表だけにあり、Publication定義との差分がない。
  • RLS対象表では、ポリシーに従う部分複製を許容するか、row_security=offで停止させるかが明文化されている。
  • 資格情報の保管場所、管理者、更新期限と、利用しているSubscriptionまたはCDCクライアントが記録されている。
  • 新ロールへの切り替え、旧ロールのNOLOGIN、権限剥奪、既存接続の終了、再接続拒否まで実行できる。

REPLICATIONの広さを抑える鍵は、属性そのものではなく、その属性を持つロールが到達できるデータベースと表、接続元、存続時間を周辺の制御で狭めることにある。Publication単位の権限がないという前提を監査項目へ明記すれば、「複製に必要」という理由だけで強い資格情報が残り続ける状態を避けられる。

共有:

ニュースレターを購読

Web3、AI、暗号資産の最新ニュースを受信箱にお届けします。

0