postgres-operator icon indicating copy to clipboard operation
postgres-operator copied to clipboard

DNS names in certificate terminate with an dot - violates standard

Open dkrizic opened this issue 2 months ago • 4 comments

I installed the operator and created a cluster named 'master' with basically default configuration:

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: master
  namespace: persistence

spec:
  config:
  postgresVersion: 16
  instances:
    - name: instance1
      replicas: 2
...

When I do a port-forward to localhost:5432 and try to connect with a Go application I get the following error

Error connecting to database: tls: failed to parse certificate from server: x509: SAN dNSName is malformed

I took a look in the the secret master-server-cert and then the tls.crt and found this:

            X509v3 Subject Alternative Name: 
                DNS:master-primary.persistence.svc.cluster.local., DNS:master-primary.persistence.svc, DNS:master-primary.persistence, DNS:master-primary, DNS:master-replicas.persistence.svc.cluster.local., DNS:master-replicas.persistence.svc, DNS:master-replicas.persistence, DNS:master-replicas

All the names that terminate with a dot are illegal according to X.509 standard. It looks like the go client library does not like the certificate. Is this a bug or do I see this wrong?

Additionally: Is there an easy way to add hosts like "localhost" or "db.example.com" (for a TCPRoute) to the certificate?

Fun fact: I am able to access the database remotely (either port-forward or TCPRoute) from the Database-Client in Golang which is Java-based. Obviously Java is more relaxed than Go regarding the certificate.

dkrizic avatar Oct 08 '25 22:10 dkrizic

I found a workaround by creating a custom certificate like (my database is called master)

# Create key and certificate for our CA
openssl genrsa -out ca.key 2048

# Create CSR data with our custom domain names, including the external ones
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt \
  -subj "/CN=PGO-Custom-CA"
cat <<EOF > csr.conf
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
CN = master-primary.persistence.svc.cluster.local

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = db.example.com
DNS.2 = master-primary.persistence.svc.cluster.local
DNS.3 = master-primary.persistence.svc
DNS.4 = master-primary.persistence
DNS.5 = master-primary
DNS.6 = master-replicas.persistence.svc.cluster.local
DNS.7 = master-replicas.persistence.svc
DNS.8 = master-replicas.persistence
DNS.9 = master-replicas
DNS.10 = localhost
EOF

# Create key for the certificate
openssl genrsa -out server.key 2048

# Create CSR
openssl req -new -key server.key -out server.csr -config csr.conf

# Sign our CSR with the CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 -sha256 -extfile csr.conf -extensions req_ext

# Create a secret in Kubernetes with ca.crt, tls.key and tls.crt
kubectl -n persistence create secret generic master-custom-cert --from-file=ca.crt --from-file=tls.key=server.key --from-file=tls.crt=server.crt

The I add this configuration to the PostgresCluster

spec:
  customTLSSecret:
    name: master-custom-cert
  customReplicationTLSSecret:
    name: master-custom-cert

I know, the replication secret should be a dedicated one, but I was lazy for now

Now I can connect to the server with sslmode=require. sslmode=verify-full works with a local copy of ca.crt.

dkrizic avatar Oct 09 '25 01:10 dkrizic

This is likely related to https://github.com/golang/go/issues/75828

pat-s avatar Oct 12 '25 15:10 pat-s

Thanks @pat-s! This indeed due to the Go issue you reference (https://github.com/golang/go/issues/75828).

Fortunately it looks like this issue is going to be addressed in the next minor releases of Go v1.24 and v1.25, which per this comment should be released soon.

So we're hoping that patch lands soon to avoid any further issues with the PGO-generated certs (such as the issue described in this thread).

andrewlecuyer avatar Oct 13 '25 21:10 andrewlecuyer

Wouldn't it make more sense to remove the SAN entries with trailing dots from the generated certificate?

dkrizic avatar Oct 14 '25 10:10 dkrizic