Security
CloudNativePGは、スタックのすべてのレイヤーにわたって「最小特権」の原則に従って、デフォルトで安全になるように設計されています。このドキュメントでは、セキュリティガバナンス、サプライチェーンの完全性、およびコード、コンテナ、クラスターの3つの異なるレイヤーで分析された技術的制御の概要を説明します。
警告
このページに含まれる情報は、Kubernetesクラスターで通常のInfoSec業務を実行することから免責されてはなりません。
Overview of Cloud Native Security についてよく理解してください
Kubernetesドキュメントのページ。 !!! 4Cのセキュリティモデルに関する注意事項 The 4C’s Security Model in Kubernetes を参照してください。
ブログ記事—
ガバナンスと信頼
脆弱性報告
重要
公開されているGitHubの問題を介してセキュリティの脆弱性を報告しないでください。 CloudNativePGは、調整された開示モデルに従います。脆弱性を非公開で報告する方法については、 Security Policy on GitHub を参照してください。
リリースの完全性とサプライチェーン
CloudNativePGは OpenSSF Software Producer Security (OSPS) Baseline に従います。 Kubernetesマニフェストやコンテナイメージを含むすべての公式リリースアセットは、暗号的に署名され検証可能です。
インストール中にこれらのアセットを検証するクイックスタート手順については、 Installation Guide を参照してください。 画像署名 および 証明書 の詳細情報
以下で見つけることができます。
コード
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” オプションが有効になっています。この機能を使用すると、ユーザーは一般に公開される前に、注意深い取り扱いが必要なセキュリティ問題を安全に報告できます。セキュリティバグを発見した場合は、この媒体を使用して報告してください。
コンテナ
CloudNativePGのすべてのコンテナイメージは、コミットのたびにCI / CDパイプラインを介して自動的にビルドされます。これらのイメージには、オペレーターのイメージだけでなく、特にサポートされているすべてのPostgreSQLバージョンのオペランドのイメージも含まれます。
** 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
コマンドを使用します。
cosign verify ghcr.io/cloudnative-pg/cloudnative-pg@sha256:<DIGEST> \
--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を取得できます。
docker buildx imagetools inspect <IMAGE> \
--format {{ json (index .SBOM "<PLATFORM>").SPDX }}
このコマンドは、JSON形式でSBOMを出力し、ソフトウェアコンポーネントとビルドの依存関係の詳細なビューを提供します。
ビルドレベルの来歴には、次を使用します。
docker buildx imagetools inspect <IMAGE> \
--format {{ json (index .Provenance "<PLATFORM>").SLSA }}
SLSAの出所の検証
slsa-verifier を使用してSLSAレベル3の来歴を検証できます。
コンテナイメージを検証するには、そのダイジェスト参照を渡します。
slsa-verifier verify-image \
ghcr.io/cloudnative-pg/cloudnative-pg@sha256:<DIGEST> \
--source-uri github.com/cloudnative-pg/cloudnative-pg
コンテナセキュリティのガイドラインとフレームワーク
コンテナレベルのセキュリティを確保するために、次のガイドラインとフレームワークが検討されています。
** Container Image Creation and Deployment Guide :** 米国国防総省DoDの防衛情報システム局DISAによって開発されました。
- CIS Benchmark for Docker :**
インターネットセキュリティセンターCISによって開発されました。
Security and Containers in CloudNativePG を参照してください。
クラスター
クラスターレベルのセキュリティでは、コントロールプレーンとノードの両方を形成するすべてのKubernetesコンポーネント、およびクラスターで実行されるアプリケーションPostgreSQLを含むが考慮されます。
ロールベースのアクセス制御RBAC
オペレーターは、cnpg-manager
という名前の専用サービスアカウントを使用してKubernetes
APIサーバーと対話します。このサービスアカウントは、通常、オペレーター名前空間、一般的にcnpg-system
にインストールされます。ただし、名前空間は、展開方法によって異なる場合があります以下のサブセクションを参照してください。
同じ名前空間に、cnpg-manager
サービスアカウントとロールの間にバインディングがあります。このロールの具体的な名前とタイプ
Role またはClusterRole
も、展開方法によって異なります。このロールは、オペレーターが正常に機能するために必要な権限を定義します。これらのロールの詳細については、展開方法に応じて、
kubectl describe clusterrole またはkubectl describe role
コマンドを使用できます。
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
へのアクセスを取得した場合、リソースの表示に制限されているget
、list 、およびwatch
権限のみがあります。ただし、無許可のユーザーがServiceAccount
へのアクセスを取得した場合、それはより重大なセキュリティ問題を示しています。
したがって、ユーザーがオペレーターのServiceAccount
および昇格した権限で他のServiceAccount
にアクセスしないようにすることが重要です。
インスタンスマネージャーによるAPIサーバーへの呼び出し
オペランドコンテナのエントリポイントであるインスタンスマネージャーは、Kubernetes
APIサーバーへのいくつかの呼び出しを行って、一部のリソースのステータスが正しく更新されることを確認し、そのPostgresクラスターに関連付けられている構成マップとシークレットにアクセスする必要があります。
。このような呼び出しは、同じPostgreSQL Cluster
リソース名を共有するオペレーターによって作成された専用のServiceAccount
を介して実行されます。
ファイル。たとえば、 myns 名前空間の汎用mypg
クラスターの権限を取得するには、次のコマンドを入力します。
kubectl get role -n myns mypg -o yaml
次に、ロールがサービスアカウントにバインドされていることを確認します。
kubectl get rolebinding -n myns mypg -o yaml
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
する必要があります。
ポッドとコンテナのセキュリティコンテキスト
ポッドまたはコンテナの特権とアクセス制御設定を定義します。
CloudNativePGは、コンテナの実行に 特権 モードを必要としません。
PostgreSQLコンテナは、 postgres システムユーザーとして実行されます。
root として実行する必要があるコンポーネントはありません。
同様に、ボリュームへのアクセスには、 特権 モードもroot
特権も必要ありません。
Kubernetesプラットフォームおよび/または管理者が適切な権限を割り当てる必要があります。
PostgreSQLコンテナは、読み取り専用のルートファイルシステムつまり書き込み可能なレイヤーなしで実行されます。
オペレーターは、PostgreSQLクラスターのすべてのポッドとコンテナのセキュリティコンテキストの設定を管理します。
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
フィールドを介して、ポッドとコンテナの両方のセキュリティコンテキストのきめの細かい制御を提供します。
例
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
restricted
プロファイル、ポッドとコンテナのセキュリティコンテキストの厳密な要件があります。
セキュリティコンテキストの制約
Security Context Constraints (SCC) を利用している環境で実行されている場合
オペレーターは、PostgreSQLクラスターポッドのセキュリティコンテキストを明示的に設定せず、ポッドが既に定義されている制限されたセキュリティコンテキストコンストレインを継承することを許可します。
AppArmorを使用してポッドアクセスを制限する
container.apparmor.security.beta.kubernetes.io
アノテーションを介して、すべてのCluster ポッド内のpostgres
、initdb 、join 、full-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 を参照してください。
詳細については、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の現在の実装は、データベース所有者と、
enableSuperuserAccess をtrue に設定して要求された場合にのみ、
postgres スーパーユーザーのパスワードと.pgpass
ファイルを自動的に作成します。
警告
enableSuperuserAccess は、オペレーターのセキュリティバイデフォルト姿勢を向上させるためにデフォルトで`false` に設定され、PostgreSQLへの変更が`Cluster` リソースの`spec` を介して宣言的な方法で実行されるマイクロサービスアプローチを促進しながら、開発者に内部のフルパワーを提供しますデータベース所有者ユーザーを介してデータベースにアクセスします。パスワードの暗号化に関する限り、CloudNativePGはPostgreSQLのデフォルト動作に従います。PostgreSQL 14以降、password_encryption はデフォルトで`scram-sha-256` に設定されますが、以前のバージョンでは`md5` に設定されています。
詳細については、PostgreSQLドキュメントのセクションを参照してください。
!!!注意 オペレーターは、enableSuperuserAccess
オプションの切り替えをサポートしています。実行中のクラスターで無効にすると、オペレーターはシークレットの内容を無視し、削除し、オペレーターが以前に生成した場合、postgres
ユーザーのパスワードをNULL
に設定しますパスワード認証を介したリモートアクセスを事実上無効にします。
!!!注意 重要]
PostgreSQL documentation で述べているように、PostgreSQLでは、一部のロール操作のログに平文のロールパスワードが含まれる場合があります。
CloudNativePGは、 postgres
ロギングステートメントロギングとErrorステートメントロギングの両方が、パスワードを使用したCREATE
/ ALTER
ROLE操作で一時的に抑制されるため、パスワードの漏洩を防ぎます。詳細については、
シークレット を参照してください。
これらのファイルを使用して、データベースへのアプリケーションのアクセスを構成できます。
デフォルトでは、すべてのレプリカは、streaming_replica
と呼ばれる特別なユーザーを使用して、現在のプライマリインスタンスに
物理非同期ストリーミングレプリケーション
で接続するように自動的に構成されます。ノード間の接続は 暗号化
され、認証は TLSクライアント証明書
を介して行われます。詳細については、
Client TLS/SSL connections ページを参照してください。デフォルトでは、オペレーターはTLS
v1.3接続を必要とします。
現在、オペレーターは、管理者がpostgresql 構成のpg_hba
セクションの一部としてマニフェストにpg_hba.conf
行を直接追加できます。マニフェストで定義された行は、デフォルトのpg_hba.conf
に追加されます。
オペレーターによるpg_hba.conf
の管理方法の詳細については、ドキュメントの マウンティングとPostgreSQLの構成 を参照してください。
管理者は、デフォルトでローカルのpostgresユーザーをデータベース内のpostgresユーザーにのみマップするpg_ident.conf
ファイルの内容をカスタマイズすることもできます。
オペレーターによるpg_ident.conf
の管理方法の詳細については、ドキュメントの マウンティングとPostgreSQLの構成 を参照してください。
ストレージ
CloudNativePGは、保存時の暗号化を基になるストレージクラスに委任します。運用環境でのデータ保護のために、保存時の暗号化をサポートするストレージクラスを選択することを強くお勧めします。