Security and Roles

BDR拡張機能はスーパーユーザーのみが作成できますが、必要に応じて、 pgextwlist 拡張機能を設定し、非スーパーユーザーがBDRを作成できるように構成できます。

BDRの構成と管理にはスーパーユーザアクセスは必要なく、お勧めしません。 BDRに必要な権限は、 PostgreSQLのデフォルトの/事前定義されたロールと同様に名前付けた、次のデフォルトの/事前定義されたロールに分割されます。

  • bdr_superuser - 最高の特権ロール、すべてのBDRテーブルとファンクションへのアクセス。

  • bdr_read_all_stats - BDRの状態を理解するのに十分な、テーブル、ビュー、およびファンクションへの読み取り専用アクセスを持つロール。

  • bdr_monitor - 現時点ではbdr_read_all_stats と同じですが、後で拡張ます。

  • bdr_application - BDRを実行しているアプリケーションに必要な最小限の権限。

  • bdr_read_all_conflicts - bdr.conflict_history ですべての競合をビューできます。

これらのBDRロールは、 BDR拡張機能のインストール時に作成されます。詳細については、 BDR Default Roles を参照してください。

BDRを管理するために、管理者がユーザデータにアクセスする必要はありません。

競合を保護するための手配については、ここで説明されています テーブルへの競合のログ 。

競合は、 BDR.conflict_history_summaryビューを使用して監視できます。

カタログテーブル

システムカタログと情報スキーマテーブルは、常にBDRによるレプリケーションから除外されます。

さらに、拡張機能が所有するテーブルはレプリケーションから除外されます。

BDRFunctionsと演算子

すべてのBDR関数は bdr スキーマで公開されています。これらの関数への呼び出しは、 search_path にbdr を置くのではなく、スキーマで修飾する必要があります。

すべてのBDR演算子はpg_catalog スキーマを介して使用できるため、ユーザーはsearch_pathからpublic スキーマを問題なく除外できます。

カタログオブジェクトに対する特権の付与

管理者は、テーブル、ビュー、ファンクションなどのカタログオブジェクトに対する明示的な特権を付与しないでください。 BDR Default Rolesに記載されているロールのいずれかを付与することにより、これらのオブジェクトへのアクセスを管理します。

この要件は、結合のいずれかの側のノードのBDR (したがってBDRカタログ)のバージョンが完全に同じでなくても、ノードグループに参加できる柔軟性の結果です。

より正確には、個々のカタログオブジェクトに対する特権が明示的に付与されている場合、結合されるノードから抽出された対応する GRANT ステートメントが適用されないため、 bdr.join_node_group() プロシージャが失敗する可能性がありノード。

ロール管理

ユーザーはPostgreSQLインスタンスのグローバルオブジェクト。 CREATE USER およびCREATE ROLE コマンドは、 BDRが実行されており、bdr.role_replication がオンになっているデータベースで実行されると、自動的に複製されます。ただし、これらのコマンドが同じPostgreSQLインスタンス内の他のデータベースで実行される場合、それらのユーザーがBDRデータベースに対する権限を持っている場合でも、これらは複製されません。

新しいBDRノードがBDRグループに参加しても、bdr_init_physical を使用してノードを追加しない限り、既存のユーザーは自動的にコピーされません。これは意図的なものであり、重要なセキュリティ機能です。 PostgreSQLでは、ユーザーはマルチプルのデータベースにアクセスできます。デフォルトでは任意のデータベースにアクセスできます。 BDRは、どのユーザーがどのデータベースにアクセスするかを知らないため、新しいノードにコピーするユーザーを安全に決定できません。

PostgreSQLでは、次のコマンドですべてのユーザーをダンプできます。

pg_dumpall --roles-only > roles.sql

次に、ファイルroles.sql を編集して、不要なユーザーを削除してから、新しく作成したノードで再実行します。 IDとアクセス管理ソリューション(IAM)によっては他のメカニズムも可能ですが、現時点では自動化されていません。

ロールとレプリケーション

ユーザが実行したDDL変更は、各ノードで同じユーザとして適用されます。

テーブルへのDML変更は、ターゲットノードでテーブル所有ユーザとして複製されます。テーブルは各ノードで同じユーザが所有することをお勧めしますが、強制ではありません。

テーブルAがノード1でユーザXが所有し、ノード2でユーザYが所有している場合、ユーザYがユーザXよりも高い権限を持っている場合、これは権限エスカレーションと見なすことができます。一部のノードにはさまざまなユースケースがあるため、これを許可しますが、セキュリティ管理者がこのシチュエーションを計画および監査できるように警告します。

行単位セキュリティポリシーが有効になっているテーブルでは、適用時にポリシーを再適用せずに変更がレプリケートされます。これは、 FORCE ROW LEVEL SECURITY が指定されている場合でも、 NO FORCE ROW LEVEL SECURITY として適用される変更と同等です。これが望ましくない場合は、すべての行の複製を回避するrow_filterを指定します。すべてのノードの行セキュリティポリシーを同一にするか、少なくとも互換性があるようにすることをお勧めしますが、強制はしません。

bdr_superuserはBDRのレプリケーションを制御し、任意のレプリケーションセットから任意のテーブルを追加/削除できることに注意してください。 bdr_superuserは、個々のテーブルに対する特権を必要とせず、持つこともお勧めしません。レプリケーションセットファンクションへのアクセスを制限する必要がある場合、これらのファンクションの制限バージョンを適切なユーザーにSECURITY DEFINER ファンクションおよびGRANT edとして実装できます。

接続ロール

新しいBDRノードを割り当てるとき、 bdr.create_node のlocal_dsn 引数およびbdr.join_node_group のjoin_target_dsn にDSNで指定されたユーザは、データベースオブジェクトを参照、作成、および管理するために頻繁に使用されます。

BDRは、これらのDSNでSUPERUSER 権限を持つロールを使用する場合でも権限昇格攻撃を防ぐように注意深く作成されています。

攻撃対象領域をさらに減らすために、より制限されたユーザを上記のDSNで指定できます。少なくとも、このようなユーザには、次の条件が満たされるように、すべてのノードで権限を付与する必要があります。

  • ユーザはREPLICATION 属性を持っています

  • データベースに対するCREATE パーミッションが付与されています

  • bdr_superuser ロールを継承します

  • 直接または所有者ロールからの権限を介して、レプリケートするすべてのデータベースオブジェクトを所有しています。

すべてのノードが参加したら、DMLおよびDDLレプリケーションを引き続き許可するために、権限を次のように減らすことができます。

  • ユーザはREPLICATION 属性を持っています。

  • bdr_superuser ロールを継承します。

権限制限

BDRは追加の制限を適用し、 TRIGGERまたはREFERENCES権限のみに依存するDDLの使用を効果的に防止します。以下のサブセクションでは、これらについて説明します。

GRANT ALL は引き続きTRIGGERとREFERENCESの両方の特権を付与するため、特権を明示的に記述することをお勧めします。 ALL の代わりにGRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE 。

外部キー特権

ALTER TABLE ... ADD FOREIGN KEY は、ユーザが参照先のテーブルに対する SELECT権限を持っている場合、または被参照のテーブルで現在のユーザがバイパスできないRLS制限が有効になっている場合にのみサポートされます。

したがって、 BDRで外部キーを作成するには REFERENCES権限では不十分です。 REFERENCES権限のみに依存することは、通常、有用ではありません。バリデーションチェックをテーブルスキャンではなくトリガーを使用して実行ため、通常、コストが高すぎます。

トリガー

PostgreSQLでは、テーブルの所有者とTRIGGER権限を付与されたユーザーの両方がトリガーを作成できます。非テーブル所有者によって付与されたトリガーは、 BDRでテーブル所有者として実行され、セキュリティの問題が発生する可能性があります。 TRIGGER権限はめったに使用されず、 PostgreSQLコアチームは「個別のTRIGGERパーミッションは廃止されたものと考えています」と述べています。

BDRは、テーブルにトリガーを作成できるユーザーに関するより厳密なルールを使用することにより、この問題を軽減します。

  • スーパーユーザ

  • bdr_superuser

  • テーブルの所有者は、 PostgreSQLと同じルールに従ってトリガーを作成できます(トリガーで使用されるファンクションのEXECUTE権限が必要です)。

  • テーブルのTRIGGER権限を持つユーザーは、テーブルと同じ所有者が所有するファンクションを使用してトリガーを作成し、標準のPostgreSQLルールを満たす場合にのみトリガーを作成できます(再度、ファンクションのEXECUTE権限が必要です)。したがって、テーブルとファンクションの両方が同じ所有者を持ち、所有者がユーザにテーブルのTRIGGER権限とファンクションのEXECUTE権限の両方を付与することにした場合、そのユーザはこのファンクションを使用してそのテーブルにトリガーを作成してもよいと想定されファンクション。

  • 表に対するTRIGGER権限を持つユーザは、EXECUTE権限を持っている場合、SECURITY DEFINER句で定義されたファンクションを使用してトリガーを作成できます。この句は、標準のPostgreSQLとBDRの両方で、ファンクションを常にファンクション自分自身の所有者のコンテキストで実行します。

上記のロジックは、 PostgreSQLでは、トリガーの所有者はそれを作成したユーザではなく、そのトリガーによって使用されるファンクションの所有者であるという事実に基づいています。

同じルールが既存のテーブルに適用され、テーブルの所有者が所有せず、 SECURITY DEFINER ファンクションを使用しないトリガーが既存のテーブルにある場合、それをレプリケーションセットに追加することはできません。

これらのチェックはBDR 3.6.19で追加されました。以前のバージョンの動作に依存するアプリケーションは、 bdr.backwards_compatibility を30618(またはそれ以下)に設定して、以前のバージョンのように動作させることができます。

BDRレプリケーションの適用は、システムレベルのデフォルトのsearch_pathのみを使用します。レプリカトリガー、ストリームトリガー、およびインデックス式関数は、他のsearch_path設定を想定する場合がありますが、適用時に実行されます。これが発生し保証にするには、デフォルトのsearch_pathのみを使用してオブジェクト参照を明確に解決するか(常にオブジェクトへの完全修飾参照、たとえばスキーマ .objectnameを使用します)、 ALTER FUNCTION … SET search_path = を使用してファンクションの検索パスを設定します。 ..影響を受ける機能。

BDRのデフォルト/事前定義されたロール

BDRの事前定義されたロールは、 BDR拡張機能のインストール時に作成されます。 BDR拡張機能がデータベースから削除された後も、ロールは引き続き存在するため、必要に応じて手動で削除する必要があることに注意してください。これにより、 BDRを同じPostgreSQLインスタンスのマルチプルのデータベースで問題なく使用できます。

GRANT ROLE DDLステートメントはBDRレプリケーションに参加しないため、クラスターの各ノードで実行必要があることに注意してください。

bdr_superuser

  • スキーマBDRのすべてのテーブルのすべての権限

  • スキーマBDRのすべてのルーチンのすべての権限

bdr_read_all_stats

に対するSELECT権限

  • bdr.conflict_history_summary

  • bdr.ddl_epoch

  • bdr.ddl_replication

  • bdr.global_consensus_journal_details

  • bdr.global_lock

  • bdr.global_locks

  • bdr.local_consensus_state

  • bdr.local_node_summary

  • bdr.node

  • bdr.node_catchup_info

  • bdr.node_conflict_resolvers

  • bdr.node_group

  • bdr.node_local_info

  • bdr.node_peer_progress

  • bdr.node_slots

  • bdr.node_summary

  • bdr.replication_sets

  • bdr.sequences

  • bdr.state_journal_details

  • bdr.stat_relation

  • bdr.stat_subscription

  • bdr.subscription

  • bdr.subscription_summary

  • bdr.tables

  • bdr.worker_errors

に対するEXECUTE権限

  • bdr.bdr_version

  • bdr.bdr_version_num

  • bdr.conflict_resolution_to_string

  • bdr.conflict_type_to_string

  • bdr.decode_message_payload

  • bdr.get_global_locks

  • bdr.get_raft_status

  • bdr.get_relation_stats

  • bdr.get_slot_flush_timestamp

  • bdr.get_sub_progress_timestamp

  • bdr.get_subscription_stats

  • bdr.peer_state_name

  • bdr.show_subscription_status

bdr_monitor

bdr_read_all_stats のすべての特権にプラス

に対するEXECUTE権限

  • bdr.monitor_group_versions

  • bdr.monitor_group_raft

  • bdr.monitor_local_replslots

bdr_application

に対するEXECUTE権限

  • column_timestampsデータ型のすべての関数

  • CRDTデータ型のすべての関数

  • bdr.alter_sequence_set_kind

  • bdr.create_conflict_trigger

  • bdr.create_transform_trigger

  • bdr.drop_trigger

  • bdr.get_configured_camo_partner

  • bdr.global_lock_table

  • bdr.is_camo_partner_connected

  • bdr.is_camo_partner_ready

  • bdr.logical_transaction_status

  • bdr.ri_fkey_trigger

  • bdr.seq_nextval

  • bdr.seq_currval

  • bdr.seq_lastval

  • bdr.trigger_get_committs

  • bdr.trigger_get_conflict_type

  • bdr.trigger_get_origin_node_id

  • bdr.trigger_get_row

  • bdr.trigger_get_type

  • bdr.trigger_get_xid

  • bdr.wait_for_camo_partner_queue

  • bdr.wait_slot_confirm_lsn

上記のファンクションの多くには、使用する前に追加の権限が必要であることに注意してください。例、 bdr.alter_sequence_set_kind を正常に実行には、テーブルの所有者である必要があります。これらの追加ルールは、特定の各ファンクションとともに文書化されています。

bdr_read_all_conflicts

BDRは、競合をbdr.conflict_history テーブルに記録します。競合はテーブルの所有者(のみ)に可視されるため、競合の履歴を読み取るために追加の権限は必要ありません。 すべてのテーブルの競合を確認できるユーザが便利な場合は、オプションでそのユーザにロールbdr_read_all_conflictsを付与できます。

検証

BDRは、次のツールとアプローチを使用して検証されています。

コベリティ

Coverity Scanは、次のルールとコーディング標準を使用して、脆弱性に対するカバレッジを提供するBDRスタックを検証するために使用されました。

  • ミスラC

  • ISO 26262

  • ISO / IEC TS 17961

  • OWASPトップ10

  • CERT C

  • CWEトップ25

  • AUTOSAR

CISベンチマーク

CIS PostgreSQL Benchmark v1、2019年12月19日は、 BDRスタックの検証に使用されました。 TPAexecのオプションとして使用可能なcis_policy.yml 構成を使用すると、Scoredテストで次の結果が得られます。

Result

Description

1.4

PASS

systemdサービスファイルが有効になっていることを確認する

1.5

PASS

データクラスターが正常に初期化されたことを確認する

2.1

PASS

ファイルのアクセス許可マスクが正しいことを確認します

2.2

PASS

PostgreSQL pg_wheelグループメンバシップが正しいことを確認します

3.1.2

PASS

ログの宛先が正しく設定されていることを確認します

3.1.3

PASS

ログ収集機構が有効になっていることを確認する

3.1.4

PASS

ログファイルの宛先ディレクトリが正しく設定されていることを確認します

3.1.5

PASS

ログファイルのファイル名パターンが正しく設定されていることを確認します

3.1.6

PASS

ログファイルのアクセス許可が正しく設定されていることを確認します

3.1.7

PASS

「log_truncate_on_rotation」が有効になっていることを確認します

3.1.8

PASS

ログファイルの最大存続時間が正しく設定されていることを確認します

3.1.9

PASS

最大ログファイルサイズが正しく設定されていることを確認します

3.1.10

PASS

正しいsyslog機能が選択されていることを確認します

3.1.11

PASS

PostgreSQL syslogメッセージのプログラム名前が正しいことを確認します

3.1.14

PASS

「debug_print_parse」が無効になっていることを確認します

3.1.15

PASS

「debug_print_rewriting」が無効になっていることを確認します

3.1.16

PASS

「debug_print_plan」が無効になっていることを確認します

3.1.17

PASS

「debug_pretty_print」が有効になっていることを確認します

3.1.18

PASS

「log_connections」が有効になっていることを確認します

3.1.19

PASS

「log_disconnections」が有効になっていることを確認します

3.1.21

PASS

「log_hostname」が正しく設定されていることを確認します

3.1.23

PASS

「log_statement」が正しく設定されていることを確認します

3.1.24

PASS

「log_timezone」が正しく設定されていることを確認します

3.2

PASS

PostgreSQL Audit Extension(pgAudit)が有効になっていることを確認します

4.1

PASS

sudoが正しく構成されていることを確認します

4.2

PASS

過剰な管理者権限が取り消されていることを確認する

4.3

PASS

過剰なファンクション権限が取り消されていることを確認する

4.4

PASS

テスト済み 過剰なDML権限が取り消されていることを確認する

5.2

Not Tested

「 ホスト 」TCP / IPソケットを介したログインが正しく構成されていることを確認します

6.2

PASS

「バックエンド」ランタイムパラメーターが正しく構成されていることを確認します

6.7

Not Tested

FIPS 140-2 OpenSSL暗号化が使用されていることを確認する

6.8

PASS

SSLが有効になっており、正しく構成されていることを確認します

7.3

PASS

WALアーカイビングが構成され機能していることを確認する

テスト5.2は手動で監査された場合に合格できますが、自動化可能なテストがないことに注意してください。

テスト6.7は、CentOSを使用したデフォルトの展開で成功しますが、Debianバリアントには追加のパッケージソフトが必要です。