セキュリティ¶
このセクションには、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が配布するコンテナイメージに**パッチレベルの更新**を提供します。
コンテナレベルのセキュリティのために、次のガイドラインとフレームワークが考慮されています。
- 米国国防総省(DoD)の国防情報システム局(DISA)によって開発された
Center for Internet Security(CIS)が開発した CIS Benchmark for Docker
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は、保存時の暗号化を基になるストレージクラスに委任します。運用環境でのデータ保護には、保存時の暗号化をサポートするストレージクラスを選択することを強くお勧めします。