クライアントTLS / SSL接続¶
CloudNativePGがTLS証明書をサポートする方法の詳細については、ページ。
CloudNativePGオペレーターは、サーバー側とクライアント側での転送中の暗号化と認証の両方でTLS
/ SSLと連携するように設計されています。
CNPGオペレーターを使用して作成されたクラスターには、TLSクライアント証明書を作成および署名するための認証局(CA)が付属しています。
kubectl のcnpg
プラグインを介して、パスワードを使用する代わりにユーザーの認証に使用できる新しいTLSクライアント証明書を発行できます。
TLS / SSL証明書を介して認証するには、次の手順を参照してください。
apiVersion: postgresql.cnpg.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 構成で変更できます)。
新しい証明書の発行¶
kubectl 用プラグインの使い方の詳細ページ。
次のように、 cluster-example PostgreSQLクラスターでapp
ユーザーの証明書を作成できます。
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で作成されます。これは、
pg_hba.conf のhostssl エントリに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.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
このPodは、CloudNativePGオペレーターが管理するシークレットをマウントします。
sslcert: TLSクライアントの公開証明書sslkey: TLSクライアント証明書の秘密鍵sslrootcert:TLS認証局証明書、インスタンスのIDを検証するために使用されるサーバー上の証明書に署名
それらは、psql (およびpgbench
のような他のlibpqベースのアプリケーション)がPostgresデータベースへのTLS暗号化接続を確立するために必要とするデフォルトのリソースを作成するために使用されます。
デフォルトでは、 psql は現在のユーザーの~/.postgresql
ディレクトリ内の証明書を検索しますが、
sslkey、sslcert、sslrootcertオプションを使用して、libpqが暗号化素材の実際の場所を指すように指定できます。上記のファイルの内容は、kubectlのcnpg
プラグインを使用して以前に作成されたシークレットから収集されます。
アプリケーションをデプロイします。
kubectl create -f cert-test.yaml
次に、作成したPodをPostgreSQLクライアントとして使用し、作成したばかりのTLS証明書を使用してSSL接続と認証を検証します。
データベースサーバーに到達できるときにアプリケーションの準備ができていることを確認するように、 readinessプローブが構成されています。
Podのコンテナ内でインタラクティブな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 15.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat
8.3.1-5), 64-bit
(1 row)