Transparent Data Encryption (TDE)
=================================

..  Important::
   TDEは、それをサポートするオペランドでのみ使用できます。EPASおよびPG Extended、バージョン15以降。

Transparent Data EncryptionTDEは、 **保存データ**
、つまりディスク上のデータベースファイルを暗号化するために複数のデータベースベンダーが使用しているテクノロジーです。ただし、TDEは使用中のデータを暗号化しません。

TDEは、バージョン15からEDB Postgres Advanced ServerおよびEDB Postgres
Extended Serverに含まれ、EDB CloudNativePG
Clusterオペレーターでサポートされています。

..  Important::
   続行する前に、時間をかけて :ref:`TDE feature in the EPAS documentation <Transparent Data Encryption (TDE)>`  を理解してください。

TDEをアクティブにすると、WALファイルとテーブルのファイルの両方が暗号化されます。データの暗号化/復号化は、アプリケーションの変更やクライアントドライバーの更新を必要とせずにデータベースによって管理されるため、ユーザーに対して完全に透過的です。

..  Note::
   以下に示すコードサンプルでは、 YAMLマニフェストの`postgresql` の`epas` サブセクションを使用してTDEをアクティブにします。 `epas` セクションを使用して、PG拡張イメージおよびEPASイメージのTDEを有効にできます。

EDB CloudNativePG クラスターは、TDEを使用する3つの方法を提供します。

- パスフレーズを含むシークレットを使用する

- カスタムパスフレーズコマンドを含むシークレットを使用する

- カスタムwrap/unwrapコマンドを含むシークレットのペアを使用する

パスフレーズシークレット
------------------------

基本的なアプローチは、パスフレーズをKubernetesシークレットに保存することです。このようなパスフレーズは、EPASバイナリキーの暗号化に使用されます。

..  Seealso::
   :ref:`the EPAS documentation <Transparent Data Encryption (TDE)>` を参照してください。

EPAS暗号化キーの詳細については、

オペレーターでTDEをアクティブにするのは簡単です。マニフェストの\ ``epas``
セクションで、 ``tde``
スタンザを使用してTDEを有効にし、TDE暗号化キーを保持するKubernetesシークレットを設定します。

例

.. code:: yaml

     […]
     postgresql:
       epas:
         tde:
           enabled: true
           secretKeyRef:
             name: tde-key
             key: key

例は次のとおりです。

::

   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: tde-key
   data:
     key: bG9zcG9sbGl0b3NkaWNlbnBpb3Bpb3Bpb2N1YW5kb3RpZW5lbmhhbWJyZWN1YW5kb3RpZW5lbmZyaW8=

   - --
   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     imageName: docker.enterprisedb.com/k8s_enterprise/edb-postgres-advanced:16
     postgresql:
       epas:
         tde:
           enabled: true
           secretKeyRef:
             name: tde-key
             key: key

     storage:
       size: 1Gi

。

..  Note::
   このファイルには、暗号化キーを保持するためのシークレットの定義も含まれています。この目的でシークレットを作成する方法に関する例については、次のセクションを参照してください。

シークレットに保存されているキーは、\ ``openssl``
を呼び出してEPAS暗号化キーをラップ/ラップ解除するためのパスフレーズとして使用されます。

パスフレーズを含むシークレットを作成する方法
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

最初にパスフレーズを選択します。ランダムに生成されたパスフレーズを使用することをお勧めしますが、この例では、パスフレーズとして\ ``PostgresRocks``
を使用し、\ ``kubectl`` に依存してシークレット定義を生成します。

.. code:: shell

   kubectl create secret generic -o yaml tde-key \
       --from-literal=key=PostgresRocks

これにより、次のようなものが返されます。

.. code:: yaml

   apiVersion: v1
   data:
     key: UG9zdGdyZXNSb2Nrcw==
   kind: Secret
   metadata:
     creationTimestamp: "YYYY-MM-DDTHH:MM:SSZ"
     name: tde-key
     namespace: default
     resourceVersion: ....
     uid: ....
   type: Opaque

クラスター内にシークレットを実際に作成するには、 ``kubectl apply``
を実行するか、上記の\ ``create`` コマンドの\ ``-o yaml``
オプションを削除してください。

カスタムパスフレーズコマンド
----------------------------

上記のクラスターマニフェストスニペットの\ ``secretKeyRef``
の代わりに、シークレットに保存されている\ ``passphraseCommand``
を指定できます。 passphraseコマンドを実行して、\ ``openssl``
で使用するパスフレーズを生成できます。

.. code:: yaml

     […]
     postgresql:
       epas:
         tde:
           enabled: true
           passphraseCommand:
             name: tde-passphrase
             key: command

passphraseコマンドは標準出力に書き込む必要があります。たとえば、単に\ ``echo my-passphrase``
を使用できます。

コマンドによって生成されたパスフレーズは、secretKeyRefが使用されたのと同じ方法、つまり\ ``openssl``
のパスフレーズ引数として使用されます。

カスタムwrap/unwrapコマンド
---------------------------

``openssl``
のデフォルトの呼び出しに依存するのではなく、wrapおよびunwrapコマンドを指定することもできます。これは、カスタムコマンドを含むシークレットを作成し、
``tde`` スタンザでこれらのシークレットを宣言することにより実行できます。

次のスニペットは、カスタムコマンドを使用してTDEが有効になっているクラスターを示しています。

.. code:: yaml

     […]
     postgresql:
       epas:
         tde:
           enabled: true
           wrapCommand:
             name: tde-wrap-command
             key: command
           unwrapCommand:
             name: tde-unwrap-command
             key: command

カスタムコマンドは、次の規則に従う必要があります。

1. カスタムwrapコマンドは、EPASがバイナリキーをフィードするために使用する標準入力からの入力を受け入れる必要があります。明示的な引数シェルのリダイレクトではなくを介してファイルに書き込む必要があります。さらに、
   file引数には文字列「%p」を指定する必要があります。これは、EPASが新しいラップされた暗号化キーファイルのファイルパスを渡すために使用するプレースホルダーです。

2. custom
   unwrapコマンドは、標準出力に書き込む必要があります。入力には明示的なファイルパス引数が必要ですシェルリダイレクトではありません。繰り返しますが、
   file引数には文字列「%p」を指定する必要があります。これは、EPASがラップされた暗号化キーファイルパスで埋められるプレースホルダーです。

例

- Wrapコマンド
  ``openssl enc -aes-128-cbc -pass pass:temp-pass -e -out %p``

- unwrapコマンド
  ``openssl enc -aes-128-cbc -pass pass:temp-pass -d -in %p``

HashiCorp Vaultを使用した例
---------------------------

次の例は、 HashiCorp
Vaultを使用して暗号化キーを保存し、それを使用してTDEをアクティブにする方法を示しています。
``vault`` CLIは、Vaultと対話するために使用され、デフォルトでEDB Postgres
Advanced Serverイメージに含まれています。

まず、ボールトを実行している場所はどこでも、Transit
Secretsエンジンを有効にし、キーを作成する必要があります。

.. code:: shell

   vault secrets enable transit
   vault write -f transit/keys/pg-tde

次に、カスタムwrap/unwrapコマンドを含むシークレットを作成します。
Wrapおよびunwrapコマンドは、EPASイメージにあるバイナリを「ラップ」します。バイナリはvault
APIと対話して、EPAS暗号化を暗号化/復号化します。

バイナリには、4つのフラグ\ ``--host`` 、\ ``--secret`` 、\ ``--key``
、および\ ``--vault-endpoint`` が必要です。 ``--host``
フラグは\ ``http://vault-host:vault-port``
のフォーマットであり、Vaultに到達するには提供する必要があります。
server\ ``--secret``
フラグは、ボールトトークンを含むKubernetesシークレットの名前であり、
``--key``
フラグは、ボールトトークンをポイントするそのシークレットのキーです。
``--vault-endpoint``
フラグは、ボールト内で作成されたキーの名前です。上記の例では、\ ``pg-tde``
です。

KubernetesでVaultオペレーターを実行している場合、次の2つのコマンドからルートトークンを取得できます。

.. code:: shell

   kubectl exec vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > cluster-keys.json
   cat cluster-keys.json | jq -r ".root_token"

.. code:: shell

   kubectl create secret generic -o yaml vault-token \
       --from-literal=wrap="/bin/vault wrap --file %p --host http://vault:8200 --secret vault-token --key token --vault-endpoint pg-tde" \
       --from-literal=unwrap="/bin/vault unwrap --file %p --host http://vault:8200 --secret vault-token --key token --vault-endpoint pg-tde" \
       --from-literal=token="hvs.whatever"

これで、シークレットを参照するクラスターを作成できます。

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: hashicorp-vault-tde
   spec:
     instances: 3
     storage:
       size: 1Gi
     postgresql:
       epas:
         tde:
           enabled: true
           wrapCommand:
             name: vault-token
             key: wrap
           unwrapCommand:
             name: vault-token
             key: unwrap
