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によるレプリケーションから除外されます。
さらに、拡張機能が所有するテーブルはレプリケーションから除外されます。
BDRの関数と演算子¶
すべての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がnode1でユーザーXが所有し、node2でユーザーYが所有しているとします。ユーザーYがユーザーXよりも高い特権を持っている場合、これは特権エスカレーションと見なされる場合があります。一部のノードにはさまざまなユースケースがあるため、これを許可しますが、セキュリティ管理者がこの状況を計画および監査できるように警告します。
行レベルのセキュリティポリシーが有効になっているテーブルでは、適用時にポリシーを再適用せずに変更がレプリケートされます。これは、
FORCE ROW LEVEL SECURITY が指定されている場合でも、
NO FORCE ROW LEVEL SECURITY
として適用される変更と同等です。これが望ましくない場合は、すべての行の複製を回避するrow_filterを指定します。すべてのノードの行セキュリティポリシーを同一にするか、少なくとも互換性があるようにすることはお勧めしますが、強制はしません。
ユーザ bdr_superuser は、
BDRのレプリケーションを制御し、レプリケーションセットにテーブルを追加または削除できます。
bdr_superuserには個々のテーブルに対する特権は必要なく、これもお勧めしません。レプリケーションセットファンクションへのアクセスを制限する必要がある場合、これらのファンクションの制限バージョンをSECURITY DEFINER
ファンクションとして実装し、適切なユーザーに付与できます。
接続ロール¶
新しい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のみを使用してオブジェクト参照を明確に解決するか(常にオブジェクトへの完全修飾参照、たとえば、schema.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_summarybdr.ddl_epochbdr.ddl_replicationbdr.global_consensus_journal_detailsbdr.global_lockbdr.global_locksbdr.local_consensus_statebdr.local_node_summarybdr.nodebdr.node_catchup_infobdr.node_conflict_resolversbdr.node_groupbdr.node_local_infobdr.node_peer_progressbdr.node_slotsbdr.node_summarybdr.replication_setsbdr.sequencesbdr.state_journal_detailsbdr.stat_relationbdr.stat_subscriptionbdr.subscriptionbdr.subscription_summarybdr.tablesbdr.worker_errors
に対するEXECUTE特権
bdr.bdr_versionbdr.bdr_version_numbdr.conflict_resolution_to_stringbdr.conflict_type_to_stringbdr.decode_message_payloadbdr.get_global_locksbdr.get_raft_statusbdr.get_relation_statsbdr.get_slot_flush_timestampbdr.get_sub_progress_timestampbdr.get_subscription_statsbdr.peer_state_namebdr.show_subscription_status
bdr_monitor¶
bdr_read_all_stats のすべての特権に加えて
に対するEXECUTE特権
bdr.monitor_group_versionsbdr.monitor_group_raftbdr.monitor_local_replslots
bdr_application¶
に対するEXECUTE特権
column_timestampsデータ型のすべての関数
CRDTデータ型のすべての関数
bdr.alter_sequence_set_kindbdr.create_conflict_triggerbdr.create_transform_triggerbdr.drop_triggerbdr.get_configured_camo_partnerbdr.global_lock_tablebdr.is_camo_partner_connectedbdr.is_camo_partner_readybdr.logical_transaction_statusbdr.ri_fkey_triggerbdr.seq_nextvalbdr.seq_currvalbdr.seq_lastvalbdr.trigger_get_committsbdr.trigger_get_conflict_typebdr.trigger_get_origin_node_idbdr.trigger_get_rowbdr.trigger_get_typebdr.trigger_get_xidbdr.wait_for_camo_partner_queuebdr.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ベンチマーク¶
BDRスタックの検証には、2019年12月19日 CIS PostgreSQL Benchmark
v1が使用されました。
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 |
「host」TCP / IPソケットを介したログインが正しく構成されていることを確認します |
6.2 |
PASS |
「バックエンド」ランタイムパラメーターが正しく構成されていることを確認します |
6.7 |
Not Tested |
FIPS 140-2 OpenSSL暗号化が使用されていることを確認する |
6.8 |
PASS |
SSLが有効になっており、正しく構成されていることを確認します |
7.3 |
PASS |
WALアーカイブが構成され機能していることを確認する |
テスト5.2は手動で監査するとPASSになりますが、自動テストはありません。
テスト6.7は、CentOSを使用したデフォルトの展開で成功しますが、Debianバリアントには追加のパッケージが必要です。