Client TLS/SSL connections

注釈

Certificates を参照

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

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

TLS / SSL証明書を使用して認証するためのこれらの手順は、

cluster-example-pg-hba.yaml マニフェストを使用してクラスターをインストールしていることを前提としています。構成より規約パラダイムによると、そのファイルは、 appと呼ばれるユーザーが所有するapp データベースを作成します。 bootstrap セクションのinitdb 構成を介して、この規則を変更できます。

新しい証明書の発行

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

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

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

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

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

出力

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.confhostssl エントリのcert 認証方法を活用するために必要です。

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

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

cert-test.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.7.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

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

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

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

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

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

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

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

kubectl create -f cert-test.yaml

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

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

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

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();"

出力

                                        version
- -------------------------------------------------------------------------------------
- -----------------
PostgreSQL 18.1 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 を設定します

および ssl_max_protocol_version

TLSv1.3 に。

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