The customer was trying to deploy Tanzu Postgres for Kubernetes 4.0 on their TKG 2.5, however, with HA and TLS configured. while following Configure TLS <Creating a TLS Secret Manually>, however it reported the following error: `SSL error: sslv3 alert unsupported certificate`
[pod/<podname>/pg-container] 2025-05-23 07:07:41,408 WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=0, status=None)) after connection broken by 'SSLError(1, '[SSL: SHUTDOWN_WHILE_IN_INIT] shutdown while in init (_ssl.c:2578)')': /api/v1/namespaces/postgresql/pods/<podname>
[pod/<podname>/pg-container] 2025-05-23 07:07:41,428 INFO: running post_bootstrap
[pod/<podname>/pg-container] 2025-05-23 07:07:41,428 INFO: establishing a new patroni heartbeat connection to postgres
[pod/<podname>/pg-container] 2025-05-23 07:07:41,436 ERROR: post_bootstrap
[pod/<podname>/pg-container] Traceback (most recent call last):
[pod/<podname>/pg-container] File "/usr/local/lib/python3.10/dist-packages/patroni/postgresql/bootstrap.py", line 429, in post_bootstrap
[pod/<podname>/pg-container] self.create_or_update_role(superuser['username'], superuser['password'], ['SUPERUSER'])
[pod/<podname>/pg-container] File "/usr/local/lib/python3.10/dist-packages/patroni/postgresql/bootstrap.py", line 409, in create_or_update_role
[pod/<podname>/pg-container] END;$$""".format(quote_literal(name), quote_ident(name, self._postgresql.connection()), ' '.join(options))
[pod/<podname>/pg-container] File "/usr/local/lib/python3.10/dist-packages/patroni/postgresql/__init__.py", line 367, in connection
[pod/<podname>/pg-container] return self._connection.get()
[pod/<podname>/pg-container] File "/usr/local/lib/python3.10/dist-packages/patroni/postgresql/connection.py", line 55, in get
[pod/<podname>/pg-container] self._connection = psycopg.connect(**self._conn_kwargs)
[pod/<podname>/pg-container] File "/usr/local/lib/python3.10/dist-packages/patroni/psycopg.py", line 123, in connect
[pod/<podname>/pg-container] ret = _connect(*args, **kwargs)
[pod/<podname>/pg-container] File "/usr/lib/python3/dist-packages/psycopg2/__init__.py", line 122, in connect
[pod/<podname>/pg-container] conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
[pod/<podname>/pg-container] psycopg2.OperationalError: connection to server at "localhost" (::1), port 5432 failed: SSL error: sslv3 alert unsupported certificate
It turns out to be server.crt contains only TLS web server auth as for ExtendedKey usage which resulted in such error:
% openssl x509 -in server.crt -text -noout
...
X509v3 Extended Key Usage:
TLS Web Server Authentication
Based on testing, the below 2 scenarios would work:
1. Exclude such Extended Key Usage
2. Include both Server and Client Authentication:
Including both serverAuth and clientAuth in a single certificate is a common practice in scenarios such as:
Such certificate should look like:
X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication
If OpenSSL was used for certification management, we can modify this via a OpenSSL configuration file, which was also mentioned in step2 of KB398523, for example, to include both server and client Auth, we can generate the OpenSSL configuration file like the following:
% cat > openssl-san.cnf << EOF
[req]
default_bits = 2048
prompt = no
default_md = sha512
distinguished_name = dn
req_extensions = req_ext
[dn]
CN = *.postgres-sample-agent.postgres-test.svc.cluster.local
[req_ext]
subjectAltName = @alt_names
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth,clientAuth
[alt_names]
DNS.1 = *.postgres-sample-agent.postgres-test.svc.cluster.local
EOF
%
and sign the certificate using such cnf(assuming that server.csr and root.crt has been prepared), for example:
% openssl x509 -req -in server.csr -CA root.crt -CAkey root.key -CAcreateserial -out server.crt -days 365 -sha512 -extensions req_ext -extfile openssl-san.cnf
After that, delete the original secret and recreate it following step2 of <Creating a TLS Secret Manually>
% kubectl delete secret <some-tls-secret> -n <postgres-instance-namespace>
% kubectl create secret generic <some-tls-secret> \
--type kubernetes.io/tls \
--from-file=ca.crt=/path/to/ca.crt \
--from-file=tls.crt=/path/to/tls.crt \
--from-file=tls.key=/path/to/tls.key \
--namespace <postgres-instance-namespace>
and recreate the pod as well:
kubectl delete -f postgres.yaml
kubectl apply -f postgres.yaml