セキュリティ

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

警告

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

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

参考

The 4C’s Security Model in Kubernetes を参照してください。

ブログ記事

コード

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

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

重要

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

コンテナ

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

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

重要

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

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

参考

Security and Containers in CloudNativePG を参照してください。

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

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

validatingwebhookconfigurations およびmutatingwebhookconfigurations オペレーターは、管理するすべてのリソースを検証および変更するために必要な両方のWebhook構成に、自己署名Webhook CAを注入します。詳細については、 Kubernetes documentation を参照してください。

volumesnapshots オペレーターは、PostgreSQLサーバーのバックアップを取るために、VolumeSnapshots オブジェクトを生成する必要があります。 VolumeSnapshotは、復元プロセスを開始する前に検証するために読み取られます。

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を使用してポッドアクセスを制限する

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

参考

edb_notranlate_2

警告

この種類のアノテーションを使用すると、クラスターが動作を停止する可能性があります。この場合、アノテーションは`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が使用するポートのリストについては、以下の「公開ポート」セクションを参照してください。

ネットワークポリシーは、このドキュメントの範囲外です。

Network policies を参照してください。

詳細については、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の現在の実装は、データベース所有者と、 enableSuperuserAccess をtrue に設定して要求された場合にのみ、 postgres スーパーユーザーのパスワードと.pgpass ファイルを自動的に作成します。

警告

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

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

重要

Password authentication を参照してください。

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

注釈

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

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

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

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

Client TLS/SSL Connections ページを参照してください。デフォルトでは、オペレーターはTLS

v1.3接続を必要とします。

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

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

重要

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

ストレージ

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