セキュリティ
============

このセクションには、CloudNativePGのセキュリティに関する情報が含まれており、コード、コンテナ、クラスターの3つの異なるレイヤーで分析されます。

..  Warning::
   このページに含まれる情報は、Kubernetesクラスターで通常のInfoSec業務を実行することから免責されてはなりません。 :ref:`Overview of Cloud Native Security <セキュリティ>` についてよく理解してください

Kubernetesドキュメントのページ。

..  Seealso::
   :ref:`The 4C’s Security Model in Kubernetes <セキュリティ>` を参照してください。

ブログ記事

コード
------

CloudNativePGのソースコードは、 CI /
CDパイプラインで直接 `GolangCI-Lint <https://github.com/golangci/golangci-lint>`_ と呼ばれるGoの人気のオープンソースリンターを使用して、
**セキュリティ問題** を含む静的分析のために *体系的にスキャンされます。
GolangCI-Lintは、同じソースコードで複数の* リンター*を実行できます。

これらの1つは `Golang Security Checker <https://github.com/securego/gosec>`_  または単に\ ``gosec``
で、ハードコードされた資格情報などのコードに隠された既知の脆弱性、脅威、弱点の発見を目的とした一連のルールに対してソースの抽象構文ツリーをスキャンするリンター、整数オーバーフロー、
SQLインジェクション-いくつか例を示します。

..  Important::
   CI / CDパイプラインの静的コード分析フェーズの障害は、CloudNativePGの配信全体のブロッカーです。つまり、各コミットはGolangCI-Lintで定義されたすべてのリンターに対して検証されます。

コンテナ
--------

CloudNativePGの一部であるすべてのコンテナイメージは、各コミットに続いてCI
/
CDパイプラインを介して自動的にビルドされます。このようなイメージには、演算子だけでなくオペランド、特にサポートされているすべてのPostgreSQLバージョンが含まれます。パイプライン内では、画像は次の方法でスキャンされます。

-  `Dockle <https://github.com/goodwithtech/dockle>`_  コンテナビルドプロセスに関するベストプラクティス用

..  Important::
   ベースイメージとパッケージレベルでセキュリティ更新が発生した場合、すべてのオペランドイメージはパイプラインによって1日1回自動的に再ビルドされ、EDBが配布するコンテナイメージの**パッチレベルの更新**を提供します。

コンテナレベルのセキュリティでは、次のガイドラインとフレームワークが考慮されています。

-  `Container Image Creation and Deployment Guide <https://dl.dod.cyber.mil/wp-content/uploads/devsecops/pdf/DevSecOps_Enterprise_Container_Image_Creation_and_Deployment_Guide_2.6-Public-Release.pdf>`_ 
   、米国国防総省DoDの防衛情報システム庁DISAによって開発されました

-  :ref:`CIS Benchmark for Docker <セキュリティ>` 
   、インターネットセキュリティセンターCISによって開発されました

..  Seealso::
   :ref:`Security and Containers in CloudNativePG <セキュリティ>` を参照してください。

EDBがCloudNativePGのコンテナレベルでのセキュリティに対して採用したアプローチの詳細については、ブログ記事を参照してください。

クラスター
----------

クラスターレベルのセキュリティでは、コントロールプレーンとノードの両方を形成するすべてのKubernetesコンポーネント、およびクラスターで実行されるアプリケーションPostgreSQLを含むが考慮されます。

ロールベースのアクセス制御RBAC
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

オペレーターは、\ ``cnpg-manager``
と呼ばれる専用のサービスアカウントを使用してKubernetes
APIサーバーと対話します。
Kubernetesでは、これはデフォルトで\ ``cnpg-system``
名前空間にインストールされ、このサービスアカウントと、オペレーターに付与されるルール/リソース/動詞のセットを定義する\ ``cnpg-manager``
クラスターロール間のクラスターロールバインディングを使用します。

..  Important::
   上記の権限は、Kubernetes APIサーバーと対話するためにオペレーターのサービスアカウント専用に予約されています。これらは、 `Cluster` 、`Pooler` 、`Backup` 、および`ScheduledBackup` リソースとのみ対話するオペレーターのユーザーは直接アクセスできません。

以下に、いくつかの例と、最も重要な理由を提供します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構成に、自己署名Webhook
CAを注入します。詳細については、 :ref:`Kubernetes documentation <カスタムポッドコントローラ>` を参照してください。

``nodes``
オペレーターはアフィニティとアンチアフィニティのラベルを取得する必要があるため、どのノードでポッドをスケジュールできるかを決定して、レプリカが同じノードにならないようにします、特にノードが別のアベイラビリティーゾーンにある場合。この権限は、ノードがスケジュールされているかどうかを判断するためにも使用され、まったく作成できないポッドの作成を回避します。

オペレーターに必要なすべての権限を表示するには、\ ``kubectl describe clusterrole cnpg-manager``
を実行できます。

インスタンスマネージャーによるAPIサーバーへの呼び出し
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

オペランドコンテナのエントリポイントであるインスタンスマネージャーは、Kubernetes
APIサーバーへのいくつかの呼び出しを行って、一部のリソースのステータスが正しく更新されることを確認し、そのPostgresクラスターに関連付けられている構成マップとシークレットにアクセスする必要があります。
。このような呼び出しは、同じPostgreSQL ``Cluster``
リソース名を共有するオペレーターによって作成された専用の\ ``ServiceAccount``
を介して実行されます。

..  Important::
   このオペランドは、APIサーバーを介してリソースの特定の限定されたサブセットにのみアクセスできます。サービスアカウントは `recommended way to access the API server from within a Pod <https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/>`_  です。

透明性を維持するために、サービスアカウントに関連付けられている権限は `roles.go <https://github.com/cloudnative-pg/cloudnative-pg/blob/main/pkg/specs/roles.go>`_ 

ファイル。たとえば、 ``myns`` 名前空間の汎用\ ``mypg``
クラスターの権限を取得するには、次のコマンドを入力します。

.. code:: bash

   kubectl get role -n myns mypg -o yaml

次に、ロールがサービスアカウントにバインドされていることを確認します。

.. code:: bash

   kubectl get rolebinding -n myns mypg -o yaml

..  Important::
   **ロールは特定の名前空間**に制限されていることに注意してください。

以下に、汎用のKubernetesリソースのサービスアカウントに関連付けられた権限の簡単な概要を提供します。

``configmaps``
インスタンスマネージャーは、カスタムモニタリングクエリなど、同じクラスターに関連する構成マップのみを読み取ることができます

``secrets``
インスタンスマネージャーは、同じクラスターに関連するシークレットのみを読み取ることができます。ストリーミングレプリケーションユーザー、アプリケーションユーザー、スーパーユーザー、LDAP認証ユーザー、クライアントCA、サーバーCA、サーバー証明書、バックアップ資格情報、カスタムモニタリングクエリー

``events``
インスタンスマネージャーは、クラスターのイベントを作成し、PostgreSQLインスタンスのライフサイクルの特定の側面についてAPIサーバーに通知できます

ここでは、代わりに、CloudNativePGに固有のリソースに関する同じ概要を提供します。

``clusters`` インスタンスマネージャーは、独自の\ ``Cluster``
リソースに対してのみ、読み取り専用権限、つまり\ ``get`` 、\ ``list``
、および\ ``watch`` を必要とします。

``clusters/status`` インスタンスマネージャーは、 ``update``
および\ ``patch`` に、自分自身の\ ``Cluster``
リソースのみのステータスを必要とします

``backups`` インスタンスマネージャーが名前空間内の\ ``Backup``
リソースを読み取るには、 ``get`` および\ ``list``
権限が必要です。さらに、オブジェクトストアに対応するものがない\ ``Backup``
オブジェクトを削除することにより、Kubernetesクラスターをクリーンアップするには、
``delete`` 権限が必要です。通常はリテンションポリシーのため

``backups/status`` インスタンスマネージャーは、\ ``update``
および\ ``patch`` に、名前空間内の\ ``Backup``
リソースのステータスを必要とします

ポッドセキュリティポリシー
^^^^^^^^^^^^^^^^^^^^^^^^^^

 :ref:`Pod Security Policy <セキュリティ>` 

これは、クラスターで実行するためにポッドが満たす必要があるセキュリティルールと仕様を定義するKubernetes方法です。
InfoSecの理由から、すべてのKubernetesプラットフォームはそれらを実装する必要があります。

CloudNativePGは、コンテナの実行に *特権* モードを必要としません。
PostgreSQLコンテナは、 ``postgres`` システムユーザーとして実行されます。
``root`` として実行する必要があるコンポーネントはありません。

同様に、ボリュームへのアクセスには、 *特権* モードまたは\ ``root``
特権も必要ありません。
Kubernetesプラットフォームおよび/または管理者は、適切な権限を適切に割り当てる必要があります。
PostgreSQLコンテナは、読み取り専用のルートファイルシステムつまり書き込み可能なレイヤーなしで実行されます。

オペレーターは、必要なセキュリティコンテキストを明示的に設定します。

AppArmorを使用してポッドアクセスを制限する
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``container.apparmor.security.beta.kubernetes.io``
アノテーションを介して、すべての\ ``Cluster`` ポッド内の\ ``postgres``
、\ ``initdb`` 、\ ``join`` 、\ ``full-recovery``
、および\ ``bootstrap-controller``
コンテナに `AppArmor <https://kubernetes.io/docs/tutorials/security/apparmor/>`_ プロファイルを割り当てることができます。

..  Seealso::
   edb_notranlate_2

..  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 <https://kubernetes.io/docs/concepts/services-networking/network-policies/>`_ 

IPおよびTCPレベルでインバウンドおよびアウトバウンドのネットワークアクセスを有効/無効にします。詳細については、
 :ref:`networking document <ネットワーキング>`  をご覧ください。

..  Important::
   オペレーターは、TCPポート8000で各インスタンスと通信して、PostgreSQLサーバーのステータスに関する情報を取得する必要があります。ネットワークポリシーを追加する場合にこれを念頭に置いて、より詳細な制御のためにCloudNativePGが使用するポートのリストについては、以下の「公開ポート」セクションを参照してください。

ネットワークポリシーは、このドキュメントの範囲外です。
 `Network policies <https://kubernetes.io/docs/concepts/services-networking/network-policies/>`_ を参照してください。

詳細については、Kubernetesドキュメントのセクションを参照してください。

公開ポート
^^^^^^^^^^

CloudNativePGは、以下の表にリストされているように、オペレーター、インスタンスマネージャー、およびオペランドレベルでポートを公開します。

.. csv-table::
  :header: System,Port number,Exposing,Name,Certificates,Authentication
  :widths: auto
  :align: left
  :class: longtable

  operator,9443,webhook server,`webhook-server`,TLS,Yes
  operator,8080,metrics,`metrics`,no TLS,No
  instance manager,9187,metrics,`metrics`,no TLS,No
  instance manager,8000,status,`status`,no TLS,No
  operand,5432,PostgreSQL instance,`postgresql`,optional TLS,Yes

PostgreSQL
^^^^^^^^^^

CloudNativePGの現在の実装は、データベース所有者と、
``enableSuperuserAccess`` を\ ``true`` に設定して要求された場合にのみ、
``postgres`` スーパーユーザーのパスワードと\ ``.pgpass``
ファイルを自動的に作成します。

..  Warning::
   CloudNativePG 1.21より前では、`enableSuperuserAccess` はデフォルトで`true` に設定されていました。この変更は、オペレーターのデフォルトセキュリティの姿勢を向上させるために実装され、PostgreSQLの変更が`Cluster` リソースの`spec` を介して宣言的な方法で実行されるマイクロサービスアプローチを促進しながら、開発者にデータベース内のフルパワーを提供しますデータベース所有者ユーザー。

パスワードの暗号化に関する限り、CloudNativePGはPostgreSQLのデフォルト動作に従います。PostgreSQL
14以降、\ ``password_encryption`` はデフォルトで\ ``scram-sha-256``
に設定されますが、以前のバージョンでは\ ``md5`` に設定されています。

..  Important::
   `Password authentication <https://www.postgresql.org/docs/current/auth-password.html>`_ を参照してください。

詳細については、PostgreSQLドキュメントのセクションを参照してください。

..  Note::
   オペレーターは、`enableSuperuserAccess` オプションのトグルをサポートしています。実行中のクラスターで無効にすると、オペレーターはシークレットの内容を無視し、削除し、オペレーターが以前に生成した場合、`postgres` ユーザーのパスワードを`NULL` に設定しますパスワード認証を介したリモートアクセスを事実上無効にします。

詳細は、 :ref:`シークレット <シークレット>` を参照してください。

これらのファイルを使用して、データベースへのアプリケーションのアクセスを構成できます。

デフォルトでは、すべてのレプリカは、\ ``streaming_replica``
と呼ばれる特別なユーザーを使用して、現在のプライマリインスタンスに
**物理非同期ストリーミングレプリケーション**
で接続するように自動的に構成されます。ノード間の接続は **暗号化**
され、認証は **TLSクライアント証明書**
を介して行われます。詳細については、
 :ref:`Client TLS/SSL Connections <新しい証明書の発行>` ページを参照してください。

現在、オペレーターは、管理者が\ ``postgresql`` 構成の\ ``pg_hba``
セクションの一部としてマニフェストに\ ``pg_hba.conf``
行を直接追加できます。マニフェストで定義された行は、デフォルトの\ ``pg_hba.conf``
に追加されます。

オペレーターによる\ ``pg_hba.conf``
の管理方法の詳細については、ドキュメントの :ref:`PostgreSQLの構成 <PostgreSQLの構成>` を参照してください。

..  Important::
   例では、Kubernetesクラスターがプライベートで安全なネットワークで実行されていることを前提としています。

ストレージ
^^^^^^^^^^

CloudNativePGは、保存時の暗号化を基になるストレージクラスに委任します。運用環境でのデータ保護のために、保存時の暗号化をサポートするストレージクラスを選択することを強くお勧めします。
