Security and roles¶
スーパーユーザーのみがBDR拡張機能を作成できます。ただし、必要に応じて、
pgextwlist
拡張機能を設定し、非スーパーユーザーがBDR拡張機能を作成できるように構成できます。
PGDの構成と管理にスーパーユーザーアクセスは必要ありません。 PGDに必要な特権は、PostgreSQLのデフォルトおよび事前定義ロールと同様に名前付けされた、次のデフォルトおよび事前定義ロールに分割されます。
bdr_superuser —すべてのPGDテーブルと関数へのアクセスを持つ最も高い特権のロール。
bdr_read_all_stats — PGDの状態を理解するのに十分な、テーブル、ビュー、および関数への読み取り専用アクセスを持つロール。
bdr_monitor —現時点では、bdr_read_all_statsと同じ。後日延長予定。
bdr_application— PGDを実行するアプリケーションに必要な最小限の特権。
bdr_read_all_conflicts —
bdr.conflict_historyのすべての競合を表示できます。
これらのPGDロールは、 BDR拡張機能のインストール時に作成されます。詳細については、 PGD default roles を参照してください。
PGDを管理するために、管理者がユーザーデータにアクセスする必要はありません。
紛争を保護するための手配は、 競合をテーブルに記録する で議論されています。
BDR.conflict_history_summary ビューを使用して、競合を監視できます。
カタログテーブル¶
システムカタログおよび情報スキーマテーブルは、PGDによるレプリケーションから常に除外されます。
さらに、拡張機能が所有するテーブルはレプリケーションから除外されます。
PGD関数と演算子¶
すべてのPGD関数はbdr
スキーマで公開されています。これらの関数への呼び出しは、search_pathにbdr
を置くのではなく、スキーマ修飾する必要があります。
すべてのPGD演算子は pg_catalog
スキーマを介して利用可能であるため、ユーザーはsearch_pathからpublic
スキーマを問題なく除外できます。
カタログオブジェクトに対する特権の付与¶
- 管理者は、テーブル、ビュー、関数などのカタログオブジェクトに対する明示的な特権を付与してはなりません。
PGD default roles で説明されているロールのいずれかを付与して、これらのオブジェクトへのアクセスを管理します。
この要件は、参加のいずれかの側のノードが完全に同じバージョンのPGD、したがってPGDカタログのバージョンを持たない場合でも、ノードグループに参加できる柔軟性の結果です。
より正確には、個々のカタログオブジェクトに対する特権が明示的に付与された場合、
bdr.join_node_group()
プロシージャは失敗する可能性があります。結合されるノードから抽出された対応する
GRANT
ステートメントは、参加するノードに適用されない可能性があるためです。
ロール管理¶
ユーザーはPostgreSQLインスタンスのグローバルオブジェクトです。
CREATE USER およびCREATE ROLE
コマンドは、PGDが実行されており、 bdr.role_replication
がオンになっているデータベースで実行される場合、自動的に複製されます。ただし、これらのコマンドが同じPostgreSQLインスタンス内の他のデータベースで実行された場合、それらのユーザーがPGDデータベースに対する権限を持っている場合でも、それらはレプリケートされません。
新しいPGDノードがPGDグループに参加すると、bdr_init_physical
を使用してノードが追加されない限り、既存のユーザーは自動的にコピーされません。この動作は意図的なものであり、重要なセキュリティ機能です。
PostgreSQLでは、ユーザーが複数のデータベースにアクセスできます。デフォルトでは、任意のデータベースにアクセスできます。
PGDは、各ユーザーがデータベースに持っているアクセスを知らないため、新しいノードにコピーするユーザーを安全に決定できません。
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
は、PGDのレプリケーションを制御し、レプリケーションセットにテーブルを追加または削除できます。
bdr_superuserには、個々のテーブルに対する特権は必要なく、お勧めしません。レプリケーションセットファンクションへのアクセスを制限する必要がある場合は、これらのファンクションの制限バージョンを
SECURITY DEFINER
ファンクションとして実装し、適切なユーザーに付与できます。
接続ロール¶
新しいPGDノードを割り当てるとき、 bdr.create_node のlocal_dsn
引数およびbdr.join_node_group のjoin_target_dsn
にDSNで指定されたユーザーは、データベースオブジェクトの参照、作成、管理に頻繁に使用されます。
PGDは、これらのDSNでSUPERUSER
権限を持つロールを使用する場合でも、特権エスカレーション攻撃を防ぐように慎重に作成されています。
攻撃対象領域をさらに減らすには、上記のDSNでより制限されたユーザーを指定できます。少なくとも、そのようなユーザーには、次の規定が満たされるように、すべてのノードに対する権限を付与する必要があります。
ユーザーが
REPLICATION属性を持っています。データベースに対する
CREATE権限が付与されています。
・ bdr_superuserロールを継承します。
直接または所有者ロールの権限から、レプリケートするすべてのデータベースオブジェクトを所有しています。
すべてのノードが参加したら、権限をさらに次のように減らして、DMLおよびDDLレプリケーションを引き続き許可できます。
ユーザーが
REPLICATION属性を持っています。
・ bdr_superuserロールを継承します。
特権制限¶
PGDは追加の制限を適用し、 TRIGGERまたはREFERENCES特権のみに依存するDDLの使用を効果的に防止します。
GRANT ALL は引き続き TRIGGER 特権と REFERENCES
特権の両方を付与するため、特権を明示的に述べることをお勧めします。たとえば、
ALL の代わりにGRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE
を使用します。
外部キー特権¶
ALTER TABLE ... ADD FOREIGN KEY
は、ユーザーが参照先のテーブルに対するSELECT権限を持っている場合、または参照先のテーブルで現在のユーザーがバイパスできないRLS制限が有効になっている場合にのみサポートされます。
したがって、 REFERENCES 特権は、PGDで外部キーを作成するのに十分ではありません。 REFERENCES特権のみに依存することは、テーブルスキャンではなくトリガーを使用して検証チェックを実行するため、通常は役に立ちません。通常、正常に使用するには高すぎます。
トリガー¶
PostgreSQLでは、テーブルの所有者とTRIGGER権限を付与された人の両方がトリガーを作成できます。非テーブル所有者によって付与されたトリガーは、PGDでテーブル所有者として実行され、セキュリティ問題が発生する可能性があります。 TRIGGER権限はめったに使用されません。 PostgreSQLコアチームは、「個別のTRIGGER権限は、廃止されたと考えるものです」と述べています。
PGDは、テーブルでトリガーを作成できるユーザーに関するより厳しいルールを使用することにより、この問題を軽減します。
スーパーユーザー。
bdr_superuser。
テーブルの所有者は、PostgreSQLと同じルールに従ってトリガーを作成できます(トリガーで使用される関数のEXECUTE権限が必要です)。
テーブルのTRIGGER権限を持つユーザーは、テーブルと同じ所有者が所有する関数を使用してトリガーを作成し、標準のPostgreSQLルールを満たしている場合にのみトリガーを作成できます。 (ファンクションに対するEXECUTE特権が必要です。)テーブルとファンクションの両方が同じ所有者を持ち、所有者がユーザにテーブルに対するTRIGGER特権とファンクションに対するEXECUTE特権の両方を与えることにしたとします。その場合、そのユーザーはこの関数を使用してそのテーブルにトリガーを作成してもよいと想定されます。
表のTRIGGER権限を持つユーザーは、EXECUTE権限を持っている場合、 SECURITY DEFINER句で定義された関数を使用してトリガーを作成できます。この句により、標準のPostgreSQLとPGDの両方で、関数が常に関数の所有者のコンテキストで実行されます。
このロジックは、PostgreSQLでは、トリガーの所有者はそれを作成したユーザーではなく、そのトリガーで使用される関数の所有者であるという事実に基づいています。
同じルールが既存のテーブルに適用され、既存のテーブルにテーブルの所有者が所有していないトリガーがあり、 SECURITY DEFINER 関数を使用しない場合、レプリケーションセットに追加できません。
これらのチェックはPGD
3.6.19で追加されました。以前のバージョンの動作に依存するアプリケーションは、
bdr.backwards_compatibility
を30618以下に設定して、以前のバージョンと同様に動作できます。
PGDレプリケーションの適用は、システムレベルのデフォルトのsearch_pathのみを使用します。レプリカトリガー、ストリームトリガー、およびインデックス式関数は、他のsearch_path設定を想定し、適用時に実行すると失敗する場合があります。これが発生しないようにするには、デフォルトのsearch_pathのみを使用してオブジェクト参照を明確に解決するか、影響を受ける関数のALTER FUNCTION ... SET search_path = ...
を使用して関数の検索パスを設定します。デフォルトのsearch_pathを使用する場合は、常にオブジェクトへの完全修飾参照(schema.objectnameなど)を使用します。
PGDのデフォルト/事前定義されたロール¶
PGDの事前定義された役割は、 BDR拡張機能のインストール時に作成されます。 BDR拡張機能がデータベースから削除された後、ロールは引き続き存在します。ドロップが必要な場合は、手動でドロップする必要があります。このプラクティスにより、PGDを同じPostgreSQLインスタンス上の複数のデータベースで問題なく使用できます。
GRANT ROLE
DDLステートメントは、PGDレプリケーションに参加しません。したがって、クラスターの各ノードでこれを実行します。
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.stat_relationbdr.stat_subscriptionbdr.subscriptionbdr.subscription_summarybdr.tables
以下に対するEXECUTE特権:
bdr.bdr_versionbdr.bdr_version_numbdr.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¶
PGDは、競合をbdr.conflict_history
テーブルにログ記録します。競合はテーブルの所有者にのみ表示されるため、競合履歴を読み取るために追加の特権は必要ありません。すべてのテーブルの競合を確認できるユーザーが便利な場合は、オプションでそのユーザーにロール
bdr_read_all_conflicts を付与できます。
検証¶
PGDは、次のツールとアプローチを使用して検証されました。
コベリティ¶
Coverity Scanは、次のルールとコーディング標準を使用して、脆弱性に対するカバレッジを提供するPGDスタックを検証するために使用されました。
ミスラC
ISO 26262
ISO / IEC TS 17961
OWASPトップ10
CERT C
CWEトップ25
AUTOSAR
CISベンチマーク¶
CIS PostgreSQL Benchmark
v1、2019年12月19日は、PGDスタックの検証に使用されました。 Trusted
Postgres Architectのオプションとして利用可能な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バリアントには追加のパッケージが必要です。