セキュリティ

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

警告

このページに含まれる情報は、Kubernetesクラスターで通常のInfoSecの職務を実行することから免責されるものであってはなりません。 Overview of Cloud Native Security に慣れてください

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

EDBがCloudNativePGのセキュリティで取ったアプローチの理解とコンテキストをより良くするためのブログ記事。

コード

CloudNativePGのソースコードは、 セキュリティの問題 を含む静的分析の目的で 体系的にスキャン されます。 GolangCI-Lintは、同じソースコードで複数の リンター を実行できます。

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

重要

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

コンテナ

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

  • Dockle :コンテナビルドプロセスに関するベストプラクティス

重要

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

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

EDBがCloudNativePGのコンテナレベルでセキュリティに取ったアプローチの詳細については、ブログ記事。

クラスター

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

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

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

重要

上記の権限は、オペレーターのサービスアカウントが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サーバーを制御するコンテナの PID1 プロセス)がKubernetes APIサーバーと安全に通信してアクションを調整し、信頼できるステータスを継続的に提供できるようにするサービスアカウントを作成する必要がありますCluster の。

services :オペレーターは、アプリケーションからPostgreSQLクラスター(または接続プーラー)へのネットワークアクセスを制御し、自動化された方法でフェールオーバー/スイッチオーバー操作を適切に管理する必要があります(たとえば、サービスの正しいエンドポイントを適切なプライマリPostgreSQLインスタンス)。

validatingwebhookconfigurations およびmutatingwebhookconfigurations :オペレーターは、自己署名Webhook CAを両方のWebhook構成に挿入します。これは、管理するすべてのリソースを検証および変更するために必要です。詳細については、

Kubernetes documentation をご覧ください。

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

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

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

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

重要

オペランドは、APIサーバーを介してリソースの特定の制限されたサブセットにのみアクセスできます。サービスアカウントは recommended way to access the API server from within a Pod です。

透明性のために、サービスアカウントに関連付けられた権限は roles.go

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

kubectl get role -n myns mypg -o yaml

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

kubectl get rolebinding -n myns mypg -o yaml

重要

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

以下に、汎用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 リソースのステータスを必要とします

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

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

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

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

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

AppArmorを使用したPodアクセスの制限

container.apparmor.security.beta.kubernetes.io アノテーションを介して、すべてのCluster ポッド内のpostgres 、initdb 、join 、full-recovery およびbootstrap-controller コンテナーに AppArmorを使用したPodアクセスの制限 プロファイルを割り当てることができます。

警告

この種のアノテーションを使用すると、クラスターが動作を停止する可能性があります。この場合、注釈を`Cluster` から安全に削除できます。

AppArmor構成はKubernetesノードレベルである必要があります。つまり、基になるオペレーティングシステムでこのオプションを有効にし、適切に構成する必要があります。

これが状況ではなく、注釈が Cluster 作成時に追加された場合、ポッドは作成されません。一方、 Cluster が作成された後にアノテーションを追加すると、クラスター内のポッドを開始できず、次のようなエラーが発生します。

metadata.annotations[container.apparmor.security.beta.kubernetes.io/postgres]: Forbidden: may not add AppArmor annotations]

このような場合は、Kubernetes管理者に連絡し、使用する適切なAppArmorプロファイルを依頼してください。

ネットワークポリシー

Cluster リソースによって作成されたポッドは、Kubernetes

ネットワークポリシー で制御できます

IPおよびTCPレベルでのインバウンドおよびアウトバウンドのネットワークアクセスを有効/無効にします。詳細については、

networking document を参照してください。

重要

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

ネットワーク ポリシーは、このドキュメントの範囲を超えています。

ネットワークポリシー を参照してください

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

公開ポート

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

System

Port number

Exposing

Name

Certificates

Authentication

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の現在の実装は、 postgres スーパーユーザーとデータベース所有者のパスワードと.pgpass ファイルを自動的に作成します。

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

重要

ユーザー名/パスワード認証 を参照してください

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

enableSuperuserAccess をfalse に設定することにより、シークレットを介したpostgres ユーザーパスワードの管理を無効にできます。

注釈

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

詳細については、 PgBouncerSecrets を参照してください。

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

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

クライアントTLS / SSL接続 ページを参照してください)。

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

pg_hba.conf がオペレーターによって管理される方法の詳細については、ドキュメントの PostgreSQL設定 を参照してください。

重要

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

ストレージ

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