Client TLS/SSL connections
==========================

..  Seealso::
   :ref:`CertificatesConfiguration <CertificatesConfiguration>` を参照

EDB Postgres for
KubernetesがTLS証明書をサポートする方法の詳細については、こちらをご覧ください。

KubernetesオペレーターのEDB
Postgresは、転送中の暗号化とサーバー側とクライアント側での認証の両方でTLS
/ SSLと連携するように設計されました。
CNPオペレーターを使用して作成されたクラスターには、TLSクライアント証明書を作成および署名するための認証局CAが付属しています。
kubectlのcnpプラグインを使用して、パスワードを使用する代わりにユーザーを認証するための新しいTLSクライアント証明書を発行できます。

TLS /
SSL証明書を使用して認証するためのこれらの手順では、マニフェストを使用してクラスターをインストールしていることを前提としています。

::

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     postgresql:
       pg_hba:
         - hostssl app all all cert

     storage:
       size: 1Gi

構成より規約パラダイムによると、そのファイルは、
appと呼ばれるユーザーが所有する\ ``app`` データベースを作成します。
``bootstrap`` セクションの\ ``initdb``
構成を介して、この規則を変更できます。

新しい証明書の発行
------------------

..  Seealso::
   :ref:`Certificates in the EDB Postgres for Kubernetes plugin <Certificates>` を参照

kubectlのプラグインの使用方法の詳細については、コンテンツをご覧ください。

次のようにして、\ ``cluster-example``
PostgreSQLクラスターにアプリユーザーの証明書を作成できます。

.. code:: shell

   kubectl cnp certificate cluster-app \
     --cnp-cluster cluster-example \
     --cnp-user app

これで、証明書を検証できるようになりました。

.. code:: shell

   kubectl get secret cluster-app \
     -o jsonpath="{.data[tls\.crt]}" \
     | base64 -d | openssl x509 -text -noout \
     | head -n 11

出力

.. code:: console


   Certificate:
     Data:
       Version: 3 (0x2)
       Serial Number:
         5d:e1:72:8a:39:9f:ce:51:19:9d:21:ff:1e:4b:24:5d
       Signature Algorithm: ecdsa-with-SHA256
       Issuer: OU = default, CN = cluster-example
       Validity
         Not Before: Mar 22 10:22:14 2021 GMT
         Not After : Mar 22 10:22:14 2022 GMT
       Subject: CN = app

ご覧のとおり、デフォルトのTLSクライアント証明書は、90日間の有効期間と、PostgreSQLのユーザー名に対応する単純なCNで作成されます。
``EXPIRE_CHECK_THRESHOLD`` および\ ``CERTIFICATE_DURATION``
パラメーターを使用して、有効性としきい値を指定できます。これは、
``pg_hba.conf`` の\ ``hostssl`` エントリの\ ``cert``
認証方法を活用するために必要です。

TLS証明書を介した接続のテスト
-----------------------------

次に、KubernetesクラスターのEDB
Postgresに接続するデモクライアントアプリケーションを構成することにより、このクライアント証明書をテストします。

``cert-test.yaml``
と呼ばれる次のマニフェストは、データベースクラスターが実行されているのと同じ名前空間にテストアプリケーションを使用してデモポッドを作成します。

.. code:: yaml

   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: cert-test
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: webtest
     template:
       metadata:
         labels:
           app: webtest
       spec:
         containers:
           - image: ghcr.io/cloudnative-pg/webtest:1.6.0
             name: cert-test
             volumeMounts:
               - name: secret-volume-root-ca
                 mountPath: /etc/secrets/ca
               - name: secret-volume-app
                 mountPath: /etc/secrets/app
             ports:
               - containerPort: 8080
             env:
               - name: DATABASE_URL
                 value: >
                   sslkey=/etc/secrets/app/tls.key
                   sslcert=/etc/secrets/app/tls.crt
                   sslrootcert=/etc/secrets/ca/ca.crt
                   host=cluster-example-rw.default.svc
                   dbname=app
                   user=app
                   sslmode=verify-full
               - name: SQL_QUERY
                 value: SELECT 1
             readinessProbe:
               httpGet:
                 port: 8080
                 path: /tx
         volumes:
           - name: secret-volume-root-ca
             secret:
               secretName: cluster-example-ca
               defaultMode: 0600
           - name: secret-volume-app
             secret:
               secretName: cluster-app
               defaultMode: 0600

このポッドは、 EDB Postgres for
Kubernetesオペレーターによって管理されるシークレットをマウントします。

- ``sslcert`` – TLSクライアントのパブリック証明書。

- ``sslkey`` – TLSクライアント証明書のプライベートキー。

- ``sslrootcert`` –
  インスタンスのIDの確認に使用するサーバー上の証明書に署名したTLS
  CA証明書。

これらは、
psqlおよびpgbenchのような他のlibpqベースのアプリケーションがPostgresデータベースへのTLS暗号化された接続を確立するために必要なデフォルトリソースを作成するために使用されます。

デフォルトでは、 psqlは現在のユーザーの\ ``~/.postgresql``
ディレクトリで証明書を検索しますが、 ``sslkey`` 、\ ``sslcert``
、および\ ``sslrootcert``
オプションを使用して、libpqを暗号化マテリアルの実際の場所を指すことができます。これらのファイルのコンテンツは、kubectlのcnpプラグインを使用して以前に作成したシークレットから収集されます。

アプリケーションを展開します。

.. code:: shell

   kubectl create -f cert-test.yaml

次に、作成したポッドをPostgreSQLクライアントとして使用して、作成したTLS証明書を使用してSSL接続と認証を検証します。

準備状況プローブは、データベースサーバーに到達できるときにアプリケーションの準備ができていることを確認するように構成されました。

接続が機能していることを確認できます。これを行うには、ポッドのコンテナ内でインタラクティブな\ ``bash``
を実行し、必要なオプションを使用してpsqlを実行します。
PostgreSQLサーバーは、読み取り/書き込みのKubernetesサービスを介して公開されます。
psqlコマンドを指定してこのサービスに接続します。

.. code:: shell

   kubectl exec -it cert-test -- bash -c "psql
   sslkey=/etc/secrets/app/tls.key sslcert=/etc/secrets/app/tls.crt
   sslrootcert=/etc/secrets/ca/ca.crt host=cluster-example-rw.default.svc dbname=app
   user=app sslmode=verify-full -c select version();"

出力

.. code:: console

                                           version
   - -------------------------------------------------------------------------------------
   - -----------------
   PostgreSQL 17.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat
   8. 3.1-5), 64-bit
   (1 row)

TLSプロトコルバージョンについて
-------------------------------

デフォルトでは、オペレーターは両方の `ssl_min_protocol_version <https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-SSL-MIN-PROTOCOL-VERSION>`_ を設定します

と `ssl_max_protocol_version <https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-SSL-MAX-PROTOCOL-VERSION>`_ 

``TLSv1.3`` に。

これは、PostgreSQLオペランドイメージに、\ ``TLSv1.3``
バージョンをサポートするOpenSSLライブラリが含まれていることを前提としています。そうでない場合、またはクライアントアプリケーションがより低いバージョン番号を必要とする場合、他のPostgres
GUCと同様に、PostgreSQL構成で手動で構成する必要があります。
