Security

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

警告

このページに含まれる情報は、Kubernetesクラスターで通常のInfoSec業務を実行することから免責されてはなりません。

Overview of Cloud Native Security についてよく理解してください

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

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

ブログ記事

コード

CloudNativePGのソースコードは、 CI / CDパイプラインに直接統合されているGoの人気のオープンソースリンター GolangCI-Lint を使用して、セキュリティ脆弱性のチェックを含む体系的な静的分析を受けます。 GolangCI-Lintは、同じソースコードで複数のリンターを実行できます。

次のツールは、セキュリティ問題を特定するために使用されます。

  • `Golang Security Checker <https://github.com/securego/gosec>`_ ``gosec`` ) ハードコードされた資格情報、整数オーバーフロー、 SQLなどの既知の脆弱性、脅威、弱点を検出するように設計された一連のルールに対してソースコードの抽象構文ツリーをスキャンするリンター注射。 GolangCI-Lintは、スイートの一部としてgosec を実行します。

  • `govulncheck <https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck>`_ : このツールはCI / CDパイプラインで実行され、Goコードまたはコンパイラーに影響を与える既知の脆弱性を報告します。既知の脆弱性を含むGoコンパイラーのバージョンでオペレーターがビルドされている場合、 govulncheck はそれを検出します。

  • `CodeQL <https://codeql.github.com/>`_ : GitHubが提供するこのツールは、セキュリティ問題をスキャンし、検出された脆弱性を含むプルリクエストをブロックします。 CodeQLは、PythonやBashなどのリポジトリ内の他の言語を除き、Goコードのみをレビューするように構成されています。

  • `Snyk <https://snyk.io/>`_ : スケジュールされたジョブで毎晩コードスキャンを実行し、コードのセキュリティとライセンスの問題に関連する新しい結果を強調する週次レポートを生成します。

CloudNativePGリポジトリには、 Security section“Private vulnerability Reporting” オプションが有効になっています。この機能を使用すると、ユーザーは一般に公開される前に、注意深い取り扱いが必要なセキュリティ問題を安全に報告できます。セキュリティバグを発見した場合は、この媒体を使用して報告してください。

注釈

CI / CDパイプラインの静的コード分析フェーズの障害は、CloudNativePGの配信プロセス全体をブロックします。すべてのコミットは、GolangCI-Lintで定義されたすべてのリンターを渡す必要があります。

コンテナ

CloudNativePGのすべてのコンテナイメージは、コミットのたびにCI / CDパイプラインを介して自動的にビルドされます。これらのイメージには、オペレーターのイメージだけでなく、特にサポートされているすべてのPostgreSQLバージョンのオペランドのイメージも含まれます。

注釈

すべてのオペランドイメージは、パイプラインによって自動的に定期的に再構築され、ベースイメージとパッケージレベルの両方で最新のセキュリティ更新が組み込まれます。これにより、コミュニティに配布されたコンテナイメージが**パッチレベルの更新**を定期的に受信できます。

CI / CDプロセス中に、次のツールを使用してイメージがスキャンされます。

  • `Dockle <https://github.com/goodwithtech/dockle>`_ : コンテナビルドプロセスのベストプラクティスを保証します。

  • `Snyk <https://snyk.io/>`_ : コンテナ内のセキュリティ問題を検出し、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 コマンドを使用します。

cosign verify ghcr.io/cloudnative-pg/cloudnative-pg@sha256:<DIGEST> \
  --certificate-identity-regexp="^https://github.com/cloudnative-pg/cloudnative-pg/" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com"

証明書

コンテナイメージには、透明性とトレーサビリティのための次の証明書が含まれています。

  • `Software Bill of Materials (SBOM) <https://docs.docker.com/build/metadata/attestations/sbom/>`_ : イメージに含まれるか、ビルドプロセス中に使用されるソフトウェアアーティファクトの包括的なリスト。 in-toto SPDX predicate standard を使用してフォーマットされました。

  • `Provenance <https://docs.docker.com/build/metadata/attestations/slsa-provenance/>`_ : SLSA Provenance に従って、イメージがビルドされた方法を詳細に示すメタデータ

フレームワーク。

次のコマンドを使用して、特定のイメージとプラットフォームのSBOMを取得できます。

docker buildx imagetools inspect <IMAGE> \
  --format {{ json (index .SBOM "<PLATFORM>").SPDX }}

このコマンドは、JSON形式でSBOMを出力し、ソフトウェアコンポーネントとビルドの依存関係の詳細なビューを提供します。

来歴には、次を使用します。

docker buildx imagetools inspect <IMAGE> \
  --format {{ json (index .Provenance "<PLATFORM>").SLSA }}

コンテナセキュリティのガイドラインとフレームワーク

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

  • `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によって開発されました。

  • **

CIS Benchmark for Docker :**

インターネットセキュリティセンターCISによって開発されました。

注釈

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

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

クラスター

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

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

オペレーターは、cnpg-manager という名前の専用サービスアカウントを使用してKubernetes APIサーバーと対話します。このサービスアカウントは、通常、オペレーター名前空間、一般的にcnpg-system にインストールされます。ただし、名前空間は、展開方法によって異なる場合があります以下のサブセクションを参照してください。

同じ名前空間に、cnpg-manager サービスアカウントとロールの間にバインディングがあります。このロールの具体的な名前とタイプ Role またはClusterRole も、展開方法によって異なります。このロールは、オペレーターが正常に機能するために必要な権限を定義します。これらのロールの詳細については、展開方法に応じて、 kubectl describe clusterrole またはkubectl describe role コマンドを使用できます。

注釈

上記の権限は、Kubernetes APIサーバーと対話するためにオペレーターのサービスアカウント専用に予約されています。 これらは、 ClusterPoolerBackupScheduledBackupDatabasePublicationSubscriptionImageCatalog 、および`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 に設定されます。次を実行して、オペレーターに必要な権限を検査できます。

kubectl describe clusterrole cnpg-manager

OLM経由

セキュリティの観点から、Operator Lifecycle ManagerOLMは、より柔軟な展開方法を提供します。すべての名前空間または特定の名前空間を監視するようにオペレーターを構成できるため、より詳細な権限管理が可能になります。

注釈

OLMでは、オペレーターを独自の名前空間に展開し、CloudNativePGクラスターに使用される特定の名前空間を監視するように構成できます。この設定は、権限を含め、より効果的にアクセスを制限するのに役立ちます。

クラスターロールのアクセス許可が必要なのはなぜですか?

現在、オペレーターがnodes およびClusterImageCatalog オブジェクトを読み取るには、ClusterRole 権限が必要です。他のすべての権限は、名前空間スコープつまりRole またはクラスター全体つまりClusterRole にすることができます。

これらの権限でも、誰かがServiceAccount へのアクセスを取得した場合、リソースの表示に制限されているgetlist 、およびwatch 権限のみがあります。ただし、無許可のユーザーがServiceAccount へのアクセスを取得した場合、それはより重大なセキュリティ問題を示しています。

したがって、ユーザーがオペレーターのServiceAccount および昇格した権限で他のServiceAccount にアクセスしないようにすることが重要です。

インスタンスマネージャーによる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 リソースに対してのみ、読み取り専用権限、つまりgetlist 、およびwatch が必要です

clusters/status

インスタンスマネージャーは、自分自身のCluster リソースのみのステータスをupdate およびpatch する必要があります

backups

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

backups/status

インスタンスマネージャーは、名前空間内のBackup リソースのステータスをupdate およびpatch する必要があります。

ポッドとコンテナのセキュリティコンテキスト

Security Context

ポッドまたはコンテナの特権とアクセス制御設定を定義します。

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

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

オペレーターは、PostgreSQLクラスターのすべてのポッドとコンテナのセキュリティコンテキストの設定を管理します。 PostgreSQLコンテナに使用される Seccomp Profile は、 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 フィールドを介して、ポッドとコンテナの両方のセキュリティコンテキストのきめの細かい制御を提供します。

注釈

セキュリティコンテキストを変更すると、PostgreSQLクラスターのセキュリティ状態に大きな影響を与える可能性があり、ポッドが正常に起動または動作しない場合があります。変更を行う前に、どのフィールドをオーバーライドするか、演算子のデフォルトとマージする方法を確認し、非運用環境で変更をテストし、必要な最小限の十分に文書化された変更を適用します。

ポッドセキュリティコンテキスト spec.podSecurityContext これにより、すべてのPostgreSQLクラスターポッドに適用されるデフォルトのPodSecurityContext をオーバーライドできます。指定すると、演算子のデフォルト設定とマージされ、明示的に設定されたフィールドの値が優先されます。

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 と同様に、演算子のデフォルトとマージします。

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

注釈

明示的に設定していないフィールドの場合、オペレーターは安全なデフォルトを適用します。これにより、部分的な構成でもセキュリティのベストプラクティスを維持できます。

注釈

これらのフィールドは、 Pod Security Standards を使用する場合に特に役立ちます。

restricted プロファイル、ポッドとコンテナのセキュリティコンテキストの厳密な要件があります。

セキュリティコンテキストの制約

Security Context Constraints (SCC) を利用している環境で実行されている場合

オペレーターは、PostgreSQLクラスターポッドのセキュリティコンテキストを明示的に設定せず、ポッドが既に定義されている制限されたセキュリティコンテキストコンストレインを継承することを許可します。

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

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

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

警告

この種類のアノテーションを使用すると、クラスターが動作を停止する可能性があります。この場合、アノテーションは`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レベルでインバウンドおよびアウトバウンドのネットワークアクセスを有効/無効にします。詳細については、 networking document をご覧ください。

注釈

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

ネットワークポリシーは、このドキュメントの範囲外です。 Network policies を参照してください。

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

公開ポート

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

System

Port number

Exposing

Name

TLS

Authentication

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

No

operand

5432

PostgreSQL instance

postgresql

Optional

Yes

PostgreSQL

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

警告

enableSuperuserAccess は、オペレーターのセキュリティバイデフォルト姿勢を向上させるためにデフォルトで`false` に設定され、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 Configuration を参照してください。

管理者は、デフォルトでローカルのpostgresユーザーをデータベース内のpostgresユーザーにのみマップするpg_ident.conf ファイルの内容をカスタマイズすることもできます。

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

注釈

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

ストレージ

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