#!/usr/bin/env bash # Generate the tidalDB inter-node TLS material (m11p7) for clusters NOT using # cert-manager: a self-signed cluster CA + ONE shared node cert whose SANs cover # every pod's stable DNS (the StatefulSet pattern). Output matches the cert-manager # Secret shape — tls.crt / tls.key / ca.crt — so the topology grpc_tls paths and # the k8s mount are identical either way. # # Usage: # scripts/gen-cluster-certs.sh [OUT_DIR] [NAMESPACE] [STATEFULSET] [HEADLESS_SVC] [N] # Defaults reproduce k8s/cluster/: out=./cluster-certs ns=tidaldb-cluster # sts=tidaldb headless=tidaldb-peers N=3 (pods tidaldb-0..2). # # Then either mount the files at /etc/tidaldb/tls, or load them as the Secret the # StatefulSet expects: # kubectl -n tidaldb-cluster create secret generic tidaldb-cluster-tls \ # --from-file=tls.crt=cluster-certs/tls.crt \ # --from-file=tls.key=cluster-certs/tls.key \ # --from-file=ca.crt=cluster-certs/ca.crt # # Local (non-k8s) clusters point each region's grpc_tls at these files directly # (ca_cert=ca.crt, server_cert=client_cert=tls.crt, server_key=client_key=tls.key). set -euo pipefail OUT_DIR="${1:-./cluster-certs}" NAMESPACE="${2:-tidaldb-cluster}" STS="${3:-tidaldb}" HEADLESS="${4:-tidaldb-peers}" N="${5:-3}" mkdir -p "$OUT_DIR" cd "$OUT_DIR" # Build the SAN list: every pod's stable headless-Service DNS + the headless and # client Services + loopback (so a local test cluster on 127.0.0.1 also verifies). SANS="DNS:${HEADLESS}.${NAMESPACE}.svc.cluster.local,DNS:${STS}.${NAMESPACE}.svc.cluster.local,DNS:localhost,IP:127.0.0.1" for i in $(seq 0 $((N - 1))); do SANS="${SANS},DNS:${STS}-${i}.${HEADLESS}.${NAMESPACE}.svc.cluster.local" done echo "==> cluster CA" openssl genrsa -out ca.key 4096 2>/dev/null openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -subj "/CN=tidaldb-cluster-ca" -out ca.crt echo "==> node leaf (SANs: ${SANS})" openssl genrsa -out tls.key 4096 2>/dev/null openssl req -new -key tls.key -subj "/CN=tidaldb-cluster" -out node.csr # serverAuth + clientAuth so the same leaf is the gRPC mTLS client identity AND # the gRPC/HTTP server identity. openssl x509 -req -in node.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -days 825 -sha256 -out tls.crt \ -extfile <(printf 'subjectAltName=%s\nextendedKeyUsage=serverAuth,clientAuth\n' "$SANS") rm -f node.csr ca.srl chmod 600 ca.key tls.key echo "==> wrote ${OUT_DIR}/{ca.crt,tls.crt,tls.key} (+ ca.key — keep offline)" echo " grpc_tls: ca_cert=ca.crt server_cert=client_cert=tls.crt server_key=client_key=tls.key"