Security ======== .. raw:: html CloudNativePGは、スタックのすべてのレイヤーにわたって「最小特権」の原則に従って、デフォルトで安全になるように設計されています。このドキュメントでは、セキュリティガバナンス、サプライチェーンの完全性、およびコード、コンテナ、クラスターの3つの異なるレイヤーで分析された技術的制御の概要を説明します。 .. Warning:: このページに含まれる情報は、Kubernetesクラスターで通常のInfoSec業務を実行することから免責されてはなりません。 `Overview of Cloud Native Security `_ についてよく理解してください Kubernetesドキュメントのページ。 .. Note:: `The 4C’s Security Model in Kubernetes `_ を参照してください。 ブログ記事 -------------- ガバナンスと信頼 ---------------- 脆弱性報告 ^^^^^^^^^^ 重要 GitHubの公開問題を介してセキュリティ脆弱性を報告しないでください。 CloudNativePGは、調整された開示モデルに従います。脆弱性を非公開で報告する方法については、 `Security Policy on GitHub `_ を参照してください。 リリースの完全性とサプライチェーン ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CloudNativePGは `OpenSSF Software Producer Security (OSPS) Baseline `_ に従います。 Kubernetesマニフェストやコンテナイメージを含むすべての公式リリースアセットは、暗号的に署名され検証可能です。 インストール中にこれらのアセットを検証するクイックスタート手順については、 :ref:`Installation Guide ` を参照してください。 :ref:`画像署名 <画像署名>` および :ref:`証明書 <証明書>` の詳細情報 以下で見つけることができます。 -------------- コード ------ CloudNativePGのソースコードは、 CI / CDパイプラインに直接統合されているGoの人気のオープンソースリンター `GolangCI-Lint `_ を使用して、セキュリティ脆弱性のチェックを含む体系的な静的分析を受けます。 GolangCI-Lintは、同じソースコードで複数のリンターを実行できます。 次のツールは、セキュリティ問題を特定するために使用されます。 - **`Golang Security Checker `_ ``gosec`` )** ハードコードされた資格情報、整数オーバーフロー、 SQLなどの既知の脆弱性、脅威、弱点を検出するように設計された一連のルールに対してソースコードの抽象構文ツリーをスキャンするリンター注射。 GolangCI-Lintは、スイートの一部として\ ``gosec`` を実行します。 - **`govulncheck `_ :** このツールはCI / CDパイプラインで実行され、Goコードまたはコンパイラーに影響を与える既知の脆弱性を報告します。既知の脆弱性を含むGoコンパイラーのバージョンでオペレーターがビルドされている場合、 ``govulncheck`` はそれを検出します。 - **`CodeQL `_ :** GitHubによって提供されるこのツールは、セキュリティ問題をスキャンし、検出された脆弱性を含むプルリクエストをブロックします。 CodeQLは、PythonやBashなどのリポジトリ内の他の言語を除き、Goコードのみをレビューするように構成されています。 - **`Snyk `_ :** スケジュールされたジョブで毎晩コードスキャンを実行し、コードのセキュリティとライセンスの問題に関連する新しい結果を強調する週次レポートを生成します。 CloudNativePGリポジトリには、 `Security section `_ で有効になっている\_“Private vulnerability Reporting”\_オプションがあります。この機能を使用すると、ユーザーは一般に公開される前に、注意深い取り扱いが必要なセキュリティ問題を安全に報告できます。セキュリティバグを発見した場合は、この媒体を使用して報告してください。 .. Note:: CI / CDパイプラインの静的コード分析フェーズの障害は、CloudNativePGの配信プロセス全体をブロックします。すべてのコミットは、GolangCI-Lintで定義されたすべてのリンターを渡す必要があります。 コンテナ -------- CloudNativePGのすべてのコンテナイメージは、コミットのたびにCI / CDパイプラインを介して自動的にビルドされます。これらのイメージには、オペレーターのイメージだけでなく、特にサポートされているすべてのPostgreSQLバージョンのオペランドのイメージも含まれます。 .. Note:: すべてのオペランドイメージは、パイプラインによって自動的に定期的に再構築され、ベースイメージとパッケージレベルの両方で最新のセキュリティ更新が組み込まれます。これにより、コミュニティに配布されたコンテナイメージが**パッチレベルの更新**を定期的に受信できます。 CI / CDプロセス中に、次のツールを使用してイメージがスキャンされます。 - **`Dockle `_ :** コンテナビルドプロセスのベストプラクティスを保証します。 - **`Snyk `_ :** コンテナ内のセキュリティ問題を検出し、GitHubインターフェイスを介して結果を報告します。 画像署名 ^^^^^^^^ 演算子と `operandimages `_ は、 `sigstore `_ の署名ツール `cosign `_ を使用して暗号的に署名されます。このプロセスはGitHub Actionsを介して自動化され、 `short-lived tokens issued through OpenID Connect `_ を活用します。 トークン発行者は\ ``https://token.actions.githubusercontent.com`` で、署名IDは `cloudnative-pg `_ リポジトリで実行されるGitHubワークフローに対応します。このワークフローでは、 `cosign-installer action `_ 署名プロセスを合理化します。 オペレーターイメージの信頼性を確認するには、イメージダイジェストで次の\ ``cosign`` コマンドを使用します。 .. code:: shell cosign verify ghcr.io/cloudnative-pg/cloudnative-pg@sha256: \ --certificate-identity-regexp="^https://github.com/cloudnative-pg/cloudnative-pg/.github/workflows/release-publish.yml@refs/tags/v" \ --certificate-oidc-issuer="https://token.actions.githubusercontent.com" 証明書 ^^^^^^ コンテナイメージには、透明性とトレーサビリティのための次の証明書が含まれています。 - \*\* `Software Bill of Materials (SBOM) `_ イメージに含まれるか、ビルドプロセス中に使用されるソフトウェアアーティファクトの包括的なリスト。 `in-toto SPDX predicate standard `_ を使用してフォーマットされました。 - **来歴** ビルドプロセスの詳細を示すメタデータ。 `SLSA GitHub Generator Github action `_ を介して生成されます。これにより、 `SLSA Level 3 assurance `_ が提供されます アーティファクトが、信頼できる分離されたGitHub Actionsランナーでプロジェクトのソースから直接ビルドされたこと。 次のコマンドを使用して、特定のイメージとプラットフォームのSBOMを取得できます。 .. code:: shell docker buildx imagetools inspect \ --format {{ json (index .SBOM "").SPDX }} このコマンドは、JSON形式でSBOMを出力し、ソフトウェアコンポーネントとビルドの依存関係の詳細なビューを提供します。 ビルドレベルの来歴には、次を使用します。 .. code:: shell docker buildx imagetools inspect \ --format {{ json (index .Provenance "").SLSA }} SLSAの出所の検証 ^^^^^^^^^^^^^^^^ `slsa-verifier `_ を使用してSLSAレベル3の来歴を検証できます。 コンテナイメージを検証するには、そのダイジェスト参照を渡します。 .. code:: shell slsa-verifier verify-image \ ghcr.io/cloudnative-pg/cloudnative-pg@sha256: \ --source-uri github.com/cloudnative-pg/cloudnative-pg コンテナセキュリティのガイドラインとフレームワーク ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ コンテナレベルのセキュリティを確保するために、次のガイドラインとフレームワークが検討されています。 - **`Container Image Creation and Deployment Guide `_ :** 米国国防総省DoDの防衛情報システム局DISAによって開発されました。 - ** `CIS Benchmark for Docker `_ :** インターネットセキュリティセンターCISによって開発されました。 .. Note:: CloudNativePGのコンテナレベルのセキュリティに関してEDBが採用したアプローチの詳細については、ブログ記事 `Security and Containers in CloudNativePG `_ を参照してください。 クラスター ---------- クラスターレベルのセキュリティでは、コントロールプレーンとノードの両方を形成するすべてのKubernetesコンポーネント、およびクラスターで実行されるアプリケーションPostgreSQLを含むが考慮されます。最初に、このセクションの残りの部分を構成する信頼モデルとセキュリティ境界を定義します。 信頼モデルとセキュリティ境界 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CloudNativePGは、セキュリティポリシーを適用するためのオペレーターとKubernetesプラットフォーム間の明確な責任の分離に従います。以下のサブセクションでは、PostgreSQLポッドに影響を与えると信頼されている人、適用境界が実際にある場所、オペレーターが管理するリソースを制限する方法、およびこれらすべてへのアクセスがRBACによって制御される方法について説明します。 信頼できるクラスターリソースライター ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``Cluster`` カスタムリソースの作成または更新権限を持つユーザーは、オペレーターが管理するPostgreSQLポッドの完全な仕様を定義すると信頼されます。これには、\ ``spec.securityContext`` 、\ ``spec.podSecurityContext`` 、\ ``spec.serviceAccountName`` などのセキュリティ重要フィールドが含まれます。オペレーターは、指示に従ってこれらの設定を適用します。クラスターライタがそれらをオーバーライドしない場合、オペレーターは強化されたデフォルトのポッドとコンテナセキュリティコンテキストを適用します :ref:`ポッドとコンテナのセキュリティコンテキスト <ポッドとコンテナのセキュリティコンテキスト>` を参照してください。 これは、すべてのKubernetesオペレーターの動作と一貫しています。オペレーターは、高レベルのインテントを低レベルのKubernetesリソースに変換する特権エージェントとして機能します。クラスターリソースへの書き込みアクセスを誰かに付与することは、生成されるポッド、サービス、PVC、およびその他の管理対象リソースに対する制御を付与することと同じです。 同じ原則が :ref:`CNPG-I plugins ` に適用されます。プラグインはPodのライフサイクルにフックし、Podが作成される前にPod仕様のフィールドを変更できます。したがって、プラグインのインストールは、クラスターリソースへの書き込みアクセスを付与することと同様に、クラスター管理者によって行われる明示的な信頼の決定です。 同じ権限がデータベース自分自身にも拡張されます。オペレーターはスーパーユーザーとしてPostgreSQLをリコンサイルするため、クラスターライタは、次のような文書化された目的のフィールドを介して、結果のクラスターに対してスーパーユーザーレベルの影響力を取得します。 - ブートストラップSQLフック ``postInitSQL`` 、\ ``postInitApplicationSQL`` 、および\ ``postInitTemplateSQL`` 、初期化時に\ ``postgres`` スーパーユーザーとして実行されます :ref:`初期化後のクエリの実行 <初期化後のクエリの実行>` を参照してください。 - :ref:`インライン管理対象ロール <インライン管理対象ロール>` ``spec.managed.roles`` ``superuser: true`` を設定するか、既存のロールのメンバーシップを付与でき、 ``COPY ... FROM PROGRAM`` などのPostgreSQL機能を使用してオペランドポッド内でコマンドを実行できます。 - カスタムPostgreSQL構成 これは意図された信頼モデルであり、特権のエスカレーションではありません。 オペランドポッドで実行されているコードは、マウントされた\ ``ServiceAccount`` の下でも実行され、独自のクラスターに関連付けられたシークレットを読み取ることができます :ref:`インスタンスマネージャーによるAPIサーバーへの呼び出し <インスタンスマネージャーによるAPIサーバーへの呼び出し>` を参照してください および :ref:`シークレット <シークレット>` )。したがって、クラスターライタは、 :ref:`名前空間の分離 <名前空間の分離>` によってクラスター自分自身の名前空間に制限されたこれらのシークレットを読み取ることができます。 .. Note:: これらの信頼境界は、プロジェクトの `self security assessment `_ でもカバーされています。 Kubernetes Admission Control ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ オペレーターは、標準のKubernetes APIを介してポッドを作成します。つまり、すべてのポッドがクラスターに構成されている完全なアドミッション制御チェーンを通過します。これには `Pod Security Admission `_ が含まれます PSA、 `Pod Security Standards `_ を適用するビルトインKubernetesメカニズム 名前空間レベル、および使用中のサードパーティポリシーエンジンで。名前空間がPSA ``restricted`` または\ ``baseline`` プロファイルを適用する場合、Kubernetes APIサーバーは、オペレーターが作成したポッドを含む、ポリシーに違反するポッドを拒否します。 上記の信頼できるクラスターライターは任意のポッドフィールドを設定できるため、このアドミッション制御チェーンオペレーターではなく、環境にポッドセキュリティポリシーを適用する境界となります。 名前空間の分離 ^^^^^^^^^^^^^^ オペレーターは、すべての管理対象リソースを親クラスターの名前空間に制限します。インスタンスポッドは常にクラスターと同じ名前空間に作成され、他の関係から推測されるのではなく明示的かつ決定論的に設定されます。 Kubernetesの所有者参照は単一の名前空間に制限されているため、オペレーターは他の名前空間にリソースの所有権を確立することもできません。 カスタムリソースの#### RBAC CloudNativePGカスタムリソースへのアクセスは、標準のKubernetes RBACによって管理されます。クラスターリソースへの書き込みアクセスは、結果のポッドの制御を意味するため、 ``cnpg.io/podPatch`` ユーザー指定パッチを管理対象ポッドに適用する ``cnpg.io/validation`` 、\ ``cnpg.io/reconciliationLoop`` のようなアノテーションは、クラスターリソース自分自身と同じRBACルールの対象となります。 特に、 ``cnpg.io/validation`` を\ ``disabled`` に設定すると、 ``cnpg.io/podPatch`` で実行される構文と適用性チェックを含む、そのクラスターのオペレーター独自の検証用アドミッションWebhookがバイパスされます。したがって、CloudNativePGのWebhook検証は勧告です。クラスターを書き込むことができるアクターと同じアクターがオフにできるため、セキュリティ境界ではありません。 Kubernetesアドミッションコントロールは、このアノテーションに関係なく、結果のポッドに適用されます。 同じ理由が\ ``DatabaseRole`` リソースに適用されます。その仕様では、\ ``superuser: true`` と、 ``postgres`` ロール自分自身を含む\ ``inRoles`` を介した既存のロールのメンバーシップが許可されています。したがって、名前空間内の\ ``DatabaseRole`` オブジェクトへの書き込みアクセスは、その名前空間のPostgreSQLクラスターへのスーパーユーザーアクセスと同等であり、 ``Cluster`` リソースへの書き込みアクセスと同じ注意が必要です。 これらのリソースへの書き込みアクセスを高特権付与として扱います。マルチテナント展開の場合、テナントを別の名前空間に分離し、Kubernetes RBACで名前空間ごとにスコープを設定し、 :ref:`名前空間の分離 <名前空間の分離>` に依存して影響を制限します。 ここで説明するRBACは、CloudNativePG独自のカスタムリソースへのアクセスを制御します。次のセクションでは、補完的な側、つまり、オペレーター自分自身が依存して、お客様に代わってKubernetesリソースを管理するRBACについて説明します。 ロールベースのアクセス制御RBAC ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ このセクションでは、上記の :ref:`RBAC on Custom Resources <#rbac-on-custom-resources>` で説明したカスタムリソースへのユーザーアクセスとは対照的に、オペレーターの_own\_ RBAC に代わってKubernetesリソースを管理するために使用するサービスアカウントとロールについて説明します。 オペレーターは、\ ``cnpg-manager`` という名前の専用サービスアカウントを使用してKubernetes APIサーバーと対話します。このサービスアカウントは、通常、オペレーター名前空間、一般的に\ ``cnpg-system`` にインストールされます。ただし、名前空間は、展開方法によって異なる場合があります以下のサブセクションを参照してください。 同じ名前空間に、\ ``cnpg-manager`` サービスアカウントとロールの間にバインディングがあります。このロールの具体的な名前とタイプ ``Role`` または\ ``ClusterRole`` も、展開方法によって異なります。このロールは、オペレーターが正常に機能するために必要な権限を定義します。これらのロールの詳細については、展開方法に応じて、 ``kubectl describe clusterrole`` または\ ``kubectl describe role`` コマンドを使用できます。 .. Note:: 上記の権限は、Kubernetes APIサーバーと対話するためにオペレーターのサービスアカウント専用に予約されています。これらは、 `Cluster` 、`Pooler` 、`Backup` 、`ScheduledBackup` 、`Database` 、`Publication` 、`Subscription` 、`ImageCatalog` 、および`ClusterImageCatalog` リソースとのみ対話するオペレーターのユーザーは直接アクセスできません。 以下に、いくつかの例と、最も重要な理由を提供します。CloudNativePGが標準のKubernetes名前空間または非名前空間リソースの完全または部分的な管理を必要とする理由。 ``configmaps`` オペレーターは、Prometheusエクスポーターモニタリングメトリックのデフォルトの構成マップを作成および管理する必要があります。 ``deployments`` オペレーターは、標準のKubernetes ``Deployment`` リソースを使用してPgBouncer接続プーラーを管理する必要があります。 ``jobs`` オペレーターは、ジョブを処理して、さまざまな\ ``Cluster`` のフェーズを管理する必要があります。 ``persistentvolumeclaims`` ``PGDATA`` が存在するボリュームは、PostgreSQL ``Cluster`` リソースの中心的な要素です。オペレーターは、選択したストレージクラスと対話して、定義されたスケジューリングポリシーに基づいて、要求されたボリュームを動的にプロビジョニングする必要があります。 ``pods`` オペレーターは、\ ``Cluster`` のインスタンスを管理する必要があります。 ``secrets`` ``Cluster`` オブジェクトに証明書とパスワードを提供しない限り、オペレーターは、ランダムに生成されたパスワードとTLS証明書をセルフプロビジョニングし、シークレットに保存することにより、「構成より規約」パラダイムを採用します。 ``serviceaccounts`` オペレーターは、インスタンスマネージャーPostgreSQLサーバーを制御するコンテナの_PID 1_プロセスがKubernetes APIサーバーと安全に通信してアクションを調整し、\ ``Cluster`` の信頼できるステータスを継続的に提供できるサービスアカウントを作成する必要があります。 ``services`` オペレーターは、アプリケーションからPostgreSQLクラスターまたは接続プーラーへのネットワークアクセスを制御し、自動化された方法でフェールオーバー/スイッチオーバー操作を適切に管理する必要がありますたとえば、サービスの正しいエンドポイントを適切なプライマリに割り当てるPostgreSQLインスタンス)。 ``validatingwebhookconfigurations`` および\ ``mutatingwebhookconfigurations`` オペレーターは、自己署名Webhook CAを両方のWebhook構成に注入します。これらは、管理するすべてのリソースを検証および変更するために必要です。詳細については、 `Kubernetes documentation `_ を参照してください。 ``volumesnapshots`` オペレーターは、PostgreSQLサーバーのバックアップを取得するために、\ ``VolumeSnapshots`` オブジェクトを生成する必要があります。 VolumeSnapshotは、復元プロセスを開始する前に検証するために読み取られます。 ``nodes`` オペレーターは、アフィニティとアンチアフィニティのラベルを取得して、ポッドをスケジュールできるノードを決定できるようにする必要があります。これは、たとえば、レプリカが同じノードでスケジュールされるのを防ぐ場合に役立ちます。ノードが異なるアベイラビリティーゾーンにある場合に特に重要です。この権限は、ノードがスケジュールされているかどうかを判断し、スケジュールされていないノードでのポッドの作成を防止、またはプライマリがスケジュールされていないノードに存在する場合にスイッチオーバーをトリガーするためにも使用されます。 デプロイメントと\ ``ClusterRole`` リソース ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 前述のように、各展開方法には、サービスアカウントの名前空間の場所、ロールバインディング、および各ロールの名前とタイプが異なる場合があります。 Kubernetesマニフェスト経由 '''''''''''''''''''''''''' Kubernetesマニフェストを使用してCloudNativePGをインストールする場合、権限はデフォルトで\ ``ClusterRoleBinding`` に設定されます。次を実行して、オペレーターに必要な権限を検査できます。 .. code:: sh kubectl describe clusterrole cnpg-manager OLM経由 ''''''' セキュリティの観点から、Operator Lifecycle ManagerOLMは、より柔軟な展開方法を提供します。すべての名前空間または特定の名前空間を監視するようにオペレーターを構成できるため、より詳細な権限管理が可能になります。 .. Note:: OLMでは、オペレーターを独自の名前空間に展開し、CloudNativePGクラスターに使用される特定の名前空間を監視するように構成できます。この設定は、権限を含め、より効果的にアクセスを制限するのに役立ちます。 クラスターロールのアクセス許可が必要なのはなぜですか? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 現在、オペレーターが\ ``nodes`` および\ ``ClusterImageCatalog`` オブジェクトを読み取るには、\ ``ClusterRole`` 権限が必要です。他のすべての権限は、名前空間スコープつまり\ ``Role`` またはクラスター全体つまり\ ``ClusterRole`` にすることができます。 これらの権限でも、誰かが\ ``ServiceAccount`` へのアクセスを取得した場合、リソースの表示に制限されている\ ``get`` 、\ ``list`` 、および\ ``watch`` 権限のみがあります。ただし、無許可のユーザーが\ ``ServiceAccount`` へのアクセスを取得した場合、それはより重大なセキュリティ問題を示しています。 したがって、ユーザーがオペレーターの\ ``ServiceAccount`` および昇格した権限で他の\ ``ServiceAccount`` にアクセスしないようにすることが重要です。 インスタンスマネージャーによるAPIサーバーへの呼び出し ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ オペランドコンテナのエントリポイントであるインスタンスマネージャーは、Kubernetes APIサーバーへのいくつかの呼び出しを行って、一部のリソースのステータスが正しく更新されることを確認し、そのPostgresクラスターに関連付けられている構成マップとシークレットにアクセスする必要があります。 。このような呼び出しは、同じPostgreSQL ``Cluster`` リソース名を共有するオペレーターによって作成された専用の\ ``ServiceAccount`` を介して実行されます。 .. Note:: このオペランドは、APIサーバーを介してリソースの特定の限定されたサブセットにのみアクセスできます。サービスアカウントは `recommended way to access the API server from within a Pod `_ です。 共有サービスアカウントを使用する ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ デフォルトでは、CloudNativePGはクラスターごとに専用の\ ``ServiceAccount`` を作成し、クラスター自分自身にちなんで名前を付けます。ただし、IAMロールAWS IRSA、GCP Workload Identity、Azure Workload Identityなどを使用するクラウド環境では、独自の\ ``ServiceAccount`` を作成する各クラスターは、新しいクラスターごとに個別のIAM構成を必要とし、複数のクラスターを管理する際のスケーリングが困難になります。 CloudNativePGでは、クラスター仕様で\ ``serviceAccountName`` フィールドを指定することにより、複数のクラスターが単一の\ ``ServiceAccount`` を共有できます。これにより、その\ ``ServiceAccount`` を使用するすべてのクラスターで機能するワンタイムIAM構成が有効になります。 重要 共有\ ``ServiceAccount`` を使用する場合、\ ``ServiceAccount`` を自分自身で作成および管理する責任があります。オペレーターは、指定された\ ``ServiceAccount`` が存在することを検証しますが、作成または変更しません。 次に、共有\ ``ServiceAccount`` を使用する例を示します。 .. code:: yaml # Create the shared ServiceAccount once apiVersion: v1 kind: ServiceAccount metadata: name: postgres-cloud-sa annotations: # AWS IRSA annotation eks.amazonaws.com/role-arn: arn:aws:iam:us-east-1:123456789012:role/PostgresRole - -- # Reference it from multiple clusters apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-prod spec: serviceAccountName: postgres-cloud-sa instances: 3 storage: size: 100Gi .. Note:: `serviceAccountName` フィールドは`serviceAccountTemplate` と相互排他的です。オペレーターに`ServiceAccount` を管理させるか、オプションで`serviceAccountTemplate` でカスタマイズするか、`serviceAccountName` で既存のを参照できますが、両方はできません。 .. Warning:: `serviceAccountName` フィールドは、一度設定されると変更できません。 `ServiceAccount` を変更する必要がある場合は、クラスターを再作成する必要があります。 .. Note:: 複数のクラスターが`ServiceAccount` を共有する場合、オペレーターはクラスターごとに個別の`Role` および`RoleBinding` を作成します。共有`ServiceAccount` は、それを使用するすべてのクラスターのKubernetes RBAC権限を蓄積します。各`Role` のスコープは特定のクラスターのリソースに狭いため、これは特権エスカレーションを構成しません。 プーラーでの共有サービスアカウントの使用 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 同じ共有\ ``ServiceAccount`` 機能は\ ``Pooler`` リソースでも使用できます。 IAM統合を使用するクラウド環境にPgBouncerプーラーを展開する場合、プーラー仕様の\ ``serviceAccountName`` フィールドを指定して、オペレーターにプーラーごとに1つ作成させる代わりに、既存の\ ``ServiceAccount`` を参照できます。 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Pooler metadata: name: pooler-prod spec: cluster: name: cluster-prod serviceAccountName: pgbouncer-cloud-sa instances: 3 pgbouncer: poolMode: session .. Warning:: クラスターと同様に、プーラーの`serviceAccountName` フィールドは、一度設定されると変更できません。 `ServiceAccount` を変更する必要がある場合は、プーラーを再作成する必要があります。 透明性を維持するために、サービスアカウントに関連付けられている権限は `roles.go `_ ファイル。たとえば、 ``myns`` 名前空間の汎用\ ``mypg`` クラスターの権限を取得するには、次のコマンドを入力します。 .. code:: bash kubectl get role -n myns mypg -o yaml 次に、ロールがサービスアカウントにバインドされていることを確認します。 .. code:: bash kubectl get rolebinding -n myns mypg -o yaml .. Note:: **ロールは特定の名前空間**に制限されていることに注意してください。 以下に、汎用のKubernetesリソースのサービスアカウントに関連付けられた権限の簡単な概要を提供します。 ``configmaps`` インスタンスマネージャーは、カスタムモニタリングクエリなど、同じクラスターに関連する構成マップのみを読み取ることができます ``secrets`` インスタンスマネージャーは、同じクラスターに関連するシークレットのみを読み取ることができます。ストリーミングレプリケーションユーザー、アプリケーションユーザー、スーパーユーザー、LDAP認証ユーザー、クライアントCA、サーバーCA、サーバー証明書、バックアップ資格情報、カスタムモニタリングクエリー ``events`` インスタンスマネージャーは、クラスターのイベントを作成し、PostgreSQLインスタンスのライフサイクルの特定の側面についてAPIサーバーに通知できます ここでは、代わりに、CloudNativePGに固有のリソースに関する同じ概要を提供します。 ``clusters`` インスタンスマネージャーは、独自の\ ``Cluster`` リソースに対してのみ、読み取り専用権限、つまり\ ``get`` 、\ ``list`` 、および\ ``watch`` が必要です ``clusters/status`` インスタンスマネージャーは、自分自身の\ ``Cluster`` リソースのみのステータスを\ ``update`` および\ ``patch`` する必要があります ``backups`` インスタンスマネージャーが名前空間内の\ ``Backup`` リソースを読み取るには、 ``get`` および\ ``list`` 権限が必要です。さらに、オブジェクトストアに対応するものがない\ ``Backup`` オブジェクトを削除することにより、Kubernetesクラスターをクリーンアップするには、 ``delete`` 権限が必要です。通常はリテンションポリシーのため ``backups/status`` インスタンスマネージャーは、名前空間内の\ ``Backup`` リソースのステータスを\ ``update`` および\ ``patch`` する必要があります。 ポッドとコンテナのセキュリティコンテキスト ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Security Context `_ ポッドまたはコンテナの特権とアクセス制御設定を定義します。 CloudNativePGは、コンテナの実行に_privileged_モードを必要としません。 PostgreSQLコンテナは、 ``postgres`` システムユーザーとして実行されます。 ``root`` として実行する必要があるコンポーネントはありません。 同様に、ボリュームアクセスには、\_privileged_モードも\ ``root`` 特権も必要ありません。 Kubernetesプラットフォームおよび/または管理者が適切な権限を割り当てる必要があります。 PostgreSQLコンテナは、読み取り専用のルートファイルシステムつまり書き込み可能なレイヤーなしで実行されます。 オペレーターは、PostgreSQLクラスターのすべてのポッドとコンテナのセキュリティコンテキストの設定を管理します。 `Seccomp Profile `_ PostgreSQLコンテナに使用するサービスは、 ``Cluster`` リソースの\ ``spec.seccompProfile`` セクションで構成できます。このセクションが空白のままの場合、コンテナはseccompプロファイル\ ``Type`` または\ ``RuntimeDefault`` 、つまりコンテナランタイムのデフォルトを使用します。 デフォルトの\ ``seccompProfile`` を使用するPostgreSQLコンテナのセキュリティコンテキストは次のようになります。 :: securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL privileged: false readOnlyRootFilesystem: true runAsNonRoot: true seccompProfile: type: RuntimeDefault セキュリティコンテキストのカスタマイズ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CloudNativePGは、それぞれ\ ``spec.podSecurityContext`` および\ ``spec.securityContext`` フィールドを介して、ポッドとコンテナの両方のセキュリティコンテキストのきめの細かい制御を提供します。 .. Note:: セキュリティコンテキストを変更すると、PostgreSQLクラスターのセキュリティ状態に大きな影響を与える可能性があり、ポッドが正常に起動または動作しない場合があります。変更を行う前に、どのフィールドをオーバーライドするか、演算子のデフォルトとマージする方法を確認し、非運用環境で変更をテストし、必要な最小限の十分に文書化された変更を適用します。 **ポッドセキュリティコンテキスト** ``spec.podSecurityContext`` これにより、すべてのPostgreSQLクラスターポッドに適用されるデフォルトの\ ``PodSecurityContext`` をオーバーライドできます。指定すると、演算子のデフォルト設定とマージされ、明示的に設定されたフィールドの値が優先されます。 例 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 podSecurityContext: runAsUser: 26 runAsGroup: 26 fsGroup: 26 supplementalGroups: [2000, 3000] fsGroupChangePolicy: "OnRootMismatch" **コンテナセキュリティコンテキスト** ``spec.securityContext`` これにより、PostgreSQLクラスターポッド内のすべてのコンテナに適用されるデフォルトの\ ``SecurityContext`` をオーバーライドできます。 ``podSecurityContext`` と同様に、演算子のデフォルトとマージします。 例 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 securityContext: allowPrivilegeEscalation: false # Note: capabilities are not merged with operator defaults. # If specified, they fully replace any defaults. capabilities: drop: - ALL add: - NET_BIND_SERVICE readOnlyRootFilesystem: true runAsNonRoot: true .. Note:: 明示的に設定していないフィールドの場合、オペレーターは安全なデフォルトを適用します。これにより、部分的な構成でもセキュリティのベストプラクティスを維持できます。 .. Note:: これらのフィールドは、 `Pod Security Standards `_ を使用する場合に特に役立ちます。 ``restricted`` プロファイル、ポッドとコンテナのセキュリティコンテキストの厳密な要件があります。 :ref:`Kubernetes Admission Control ` で説明しているように、結果のPodにこのようなプロファイルを適用するのは、オペレーターではなくこのアドミッションチェーンです。 セキュリティコンテキストの制約 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Security Context Constraints (SCC) `_ を利用している環境で実行されている場合 オペレーターは、PostgreSQLクラスターポッドのセキュリティコンテキストを明示的に設定せず、ポッドが既に定義されている制限されたセキュリティコンテキストコンストレインを継承することを許可します。 AppArmorを使用してポッドアクセスを制限する ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``container.apparmor.security.beta.kubernetes.io`` アノテーションを介して、すべての\ ``Cluster`` ポッド内の\ ``postgres`` 、\ ``initdb`` 、\ ``join`` 、\ ``full-recovery`` 、および\ ``bootstrap-controller`` コンテナに `AppArmor `_ プロファイルを割り当てることができます。例 .. code:: yaml kind: Cluster metadata: name: cluster-apparmor annotations: container.apparmor.security.beta.kubernetes.io/postgres: runtime/default container.apparmor.security.beta.kubernetes.io/initdb: runtime/default container.apparmor.security.beta.kubernetes.io/join: runtime/default .. Warning:: この種類のアノテーションを使用すると、クラスターが動作を停止する可能性があります。この場合、アノテーションは`Cluster` から安全に削除できます。 AppArmor構成はKubernetesノードレベルである必要があります。つまり、基になるオペレーティングシステムでこのオプションを有効にし、適切に構成する必要があります。 これは状況ではなく、アノテーションが\ ``Cluster`` 作成時に追加された場合、ポッドは作成されません。一方、\ ``Cluster`` が作成された後にアノテーションを追加すると、クラスター内のポッドは起動できず、次のようなエラーが発生します。 :: metadata.annotations[container.apparmor.security.beta.kubernetes.io/postgres]: Forbidden: may not add AppArmor annotations] このような場合、Kubernetes管理者に連絡し、使用する適切なAppArmorプロファイルを聞いてください。 ネットワークポリシー ^^^^^^^^^^^^^^^^^^^^ ``Cluster`` リソースによって作成されたポッドは、Kubernetesによって制御できます `network policies `_ IPおよびTCPレベルでインバウンドおよびアウトバウンドのネットワークアクセスを有効/無効にします。詳細については、 :ref:`networking document ` をご覧ください。 .. Note:: オペレーターは、TCPポート8000で各インスタンスと通信して、PostgreSQLサーバーのステータスに関する情報を取得する必要があります。ネットワークポリシーを追加する場合にこれを念頭に置いて、より詳細な制御のためにCloudNativePGが使用するポートのリストについては、以下の「公開ポート」セクションを参照してください。 ネットワークポリシーは、このドキュメントの範囲外です。 `Network policies `_ を参照してください。 詳細については、Kubernetesドキュメントのセクションを参照してください。 公開ポート ^^^^^^^^^^ CloudNativePGは、以下の表にリストされているように、オペレーター、インスタンスマネージャー、およびオペランドレベルでポートを公開します。 .. csv-table:: :header: System,Port number,Exposing,Name,TLS,Authentication :widths: auto :align: left :class: longtable operator,9443,webhook server,`webhook-server`,Yes,Yes operator,8080,metrics,`metrics`,No,No instance manager,9187,metrics,`metrics`,Optional,No instance manager,8000,status,`status`,Yes,Partial (1) operand,5432,PostgreSQL instance,`postgresql`,Optional,Yes (1)ステータス、状態、およびプローブエンドポイントは認証されていません。 :ref:`オペレーターからインスタンスへの認証 `GHSA-7qwx-x8ff-3px9` <オペレーターからインスタンスへの認証 `GHSA-7qwx-x8ff-3px9`>` で説明しているように、機密エンドポイントバックアップ、\ ``pg_controldata`` 、部分的なWALアーカイブ、およびインスタンスマネージャーのアップグレードは、オペレーターのクライアント証明書が必要です 以下。 オペレーターからインスタンスへの認証 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ オペレーターは、起動時にメモリに自己署名ECDSAクライアント証明書を生成し、クラスターの\ ``.status.operatorCertificateFingerprint`` でSHA-256公開キーフィンガープリントを公開します。インスタンスマネージャーは、そのフィンガープリントを固定し、一致する証明書を提示しない機密エンドポイントbackup、\ ``pg_controldata`` 、部分的なWALアーカイブ、およびインスタンスマネージャーのアップグレードへの呼び出しを拒否します。ステータス、状態、およびプローブエンドポイントは認証されないままです。 証明書はディスクに書き込まれることはなく、オペレーターが再起動するたびに再生成されるため、CA検証ではなくフィンガープリントのピンニングから信頼が得られます。 この保護には、ステータスポート **がTLSで提供される必要があります** というハード要件があります。これは、v1.24以降のデフォルトです。クライアント証明書はTLS接続でのみ提示できるため、ステータスポートがTLSを使用する場合にのみ、オペレーターが保護されたエンドポイントに到達できます。 .. Warning:: ステータスポートがTLSで提供されていない場合、インスタンスマネージャーはオペレーターを認証できず、`401 Unauthorized` で保護されたエンドポイントbackup、`pg_controldata` 、部分的なWALアーカイブ、およびインスタンスマネージャーのアップグレードへのすべての呼び出しを**永久に**拒否します。これは一時的な状態ではなく、自然に解決されることはありません。インスタンスマネージャーがこの認証を強制するバージョンにアップグレードされると、v1.24より古いオペレーターによって作成されたインスタンスに影響を与える可能性があります。このようなインスタンスは、TLSでポッドが再作成されるようにロールアウトする必要があります。有効なステータスポート。新しく作成されたインスタンスは常にステータスポートでTLSを有効にし、影響を受けません。 PostgreSQL ^^^^^^^^^^ CloudNativePGの現在の実装は、データベース所有者と、 ``enableSuperuserAccess`` を\ ``true`` に設定して要求された場合にのみ、 ``postgres`` スーパーユーザーのパスワードと\ ``.pgpass`` ファイルを自動的に作成します。 .. Warning:: `enableSuperuserAccess` は、オペレーターのセキュリティバイデフォルト姿勢を向上させるためにデフォルトで`false` に設定され、PostgreSQLへの変更が`Cluster` リソースの`spec` を介して宣言的な方法で実行されるマイクロサービスアプローチを促進しながら、開発者に内部のフルパワーを提供しますデータベース所有者ユーザーを介してデータベースにアクセスします。 パスワードの暗号化に関する限り、CloudNativePGはPostgreSQLのデフォルト動作に従います。PostgreSQL 14以降、\ ``password_encryption`` はデフォルトで\ ``scram-sha-256`` に設定されますが、以前のバージョンでは\ ``md5`` に設定されています。 .. Note:: `Password authentication `_ を参照してください。 詳細については、PostgreSQLドキュメントのセクションを参照してください。 .. Note:: オペレーターは、`enableSuperuserAccess` オプションのトグルをサポートしています。実行中のクラスターで無効にすると、オペレーターはシークレットの内容を無視し、削除し、オペレーターが以前に生成した場合、`postgres` ユーザーのパスワードを`NULL` に設定しますパスワード認証を介したリモートアクセスを事実上無効にします。 .. Note:: `PostgreSQL documentation `_ で記載されているように、PostgreSQLでは、一部のロール操作のログに平文のロールパスワードが含まれる場合があります。 CloudNativePGは、 `postgres` ロギングステートメントロギングとErrorステートメントロギングの両方が、パスワードを使用したCREATE / ALTER ROLE操作で一時的に抑制されるため、パスワードの漏洩を防ぎます。 詳細については、 :ref:`シークレット <シークレット>` を参照してください。 これらのファイルを使用して、データベースへのアプリケーションのアクセスを構成できます。 デフォルトでは、すべてのレプリカは、\ ``streaming_replica`` と呼ばれる特別なユーザーを使用して、現在のプライマリインスタンスに **物理非同期ストリーミングレプリケーション** で接続するように自動的に構成されます。ノード間の接続は **暗号化** され、認証は **TLSクライアント証明書** を介して行われます。詳細については、 :ref:`Client TLS/SSL connections ` ページを参照してください。デフォルトでは、オペレーターはTLS v1.3接続を必要とします。 現在、オペレーターは、管理者が\ ``postgresql`` 構成の\ ``pg_hba`` セクションの一部としてマニフェストに\ ``pg_hba.conf`` 行を直接追加できます。マニフェストで定義された行は、デフォルトの\ ``pg_hba.conf`` に追加されます。 オペレーターによる\ ``pg_hba.conf`` の管理方法の詳細については、ドキュメントの :ref:`マウンティングとPostgreSQLの構成 <マウンティングとPostgreSQLの構成>` を参照してください。 管理者は、デフォルトでローカルのpostgresユーザーをデータベース内のpostgresユーザーにのみマップする\ ``pg_ident.conf`` ファイルの内容をカスタマイズすることもできます。 オペレーターによる\ ``pg_ident.conf`` の管理方法の詳細については、ドキュメントの :ref:`マウンティングとPostgreSQLの構成 <マウンティングとPostgreSQLの構成>` を参照してください。 .. Note:: 例では、Kubernetesクラスターがプライベートで安全なネットワークで実行されていることを前提としています。 スキーマの解決と\ ``search_path`` の強化 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ データベースに対する特権を持つユーザーは、\ ``public`` などの書き込み可能なスキーマにオブジェクトファンクション、演算子、テーブル、またはタイプを植え付け、データベースまたはロールレベルの\ ``search_path`` たとえば ``ALTER DATABASE ... SET search_path`` または\ ``ALTER ROLE ... SET search_path`` を変更できます。後でそのデータベースに接続する特権セッションは、テナント制御の\ ``search_path`` を継承するため、クエリのいずれかにおける非修飾参照は、目的のオブジェクトではなく植えられたオブジェクトに解決される場合があります。これは、 `CWE-426 (Untrusted Search Path) `_ に似た特権エスカレーションベクターであり、よく知られた `CVE-2018-1058 `_ と同じクラスの問題です。 これを防ぐために、CloudNativePGは、データベースまたは接続ロールで構成されている\ ``search_path`` に関係なく、PostgreSQLへの接続を開くすべての接続で\ ``search_path`` を\ ``pg_catalog, public, pg_temp`` の固定値に固定します。 - ``pg_catalog`` が最初に検索されるため、ビルトインオブジェクトは常に別のスキーマに植えられた同じ名前のオブジェクトより優先されます。 - ``pg_temp`` セッションプライベート一時スキーマは、最初に検索されるのではなく最後に検索されるため、リレーションまたはデータ型をシャドウできません。 さらに、PgBouncer統合で使用される\ ``SECURITY DEFINER`` ルックアップファンクションは、独自の固定された\ ``search_path`` で作成され、モニタリングクエリーは、 :ref:`バックアップの進行状況のモニタリング <バックアップの進行状況のモニタリング>` で説明しているように\ ``search_path`` が固定されているトランザクション内で実行されます。 .. Note:: ユーザー作成SQLブートストラップ中の`postInitSQL` /`postInitApplicationSQL` /`postInitTemplateSQL` 、および論理インポートのインポート後クエリーは、標準の`"$user", public` 解像度で実行されるため、プレーンのPostgreSQLセッションと同様に動作し続けます。 `search_path` から独立する必要がある場合、これらのスクリプトのオブジェクト参照をスキーマ修飾します。 ストレージ ^^^^^^^^^^ CloudNativePGは、保存時の暗号化を基になるストレージクラスに委任します。運用環境でのデータ保護のために、保存時の暗号化をサポートするストレージクラスを選択することを強くお勧めします。