tidaldb/scripts/gen-cluster-certs.sh
jx12n 005e292cbb fix(m11): review remediation + tidal-stress perf sweep + perf wave 2
Resolve all BLOCKER/CRITICAL/WARNING findings from the m11p7/p8 review:
- tidalctl restore: safe_join path-traversal/Zip-Slip guard + fsync on write
- corrupt-WAL checkpoint_seq guard; PITR archive-before-delete
- cluster: x-tidal-relayed audit-dedup marker; forward_failures counts 5xx
- mTLS/HTTP-TLS handshake hardening; accept-loop EMFILE backoff
- per-principal rate-limit + node-token marker-pinning tests
- self-heal tier-3 coverage; 5 router-auth tests

tidal-stress: measurement-fidelity fixes (schedule-lag p99/max, exact
feed-over-SLO verdict, shed annotation) + typed Body, workload.next
184ns->68ns, RoundRobin len==1 short-circuit, HeaderValue cache;
new benches/hotpath.rs + lib.rs.

perf wave 2: signal_snapshot SmallVec/SignalKey carrier; one-get-per-type
ranking pre-pass.
2026-06-13 12:28:04 -06:00

69 lines
3.2 KiB
Bash
Executable File

#!/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"
# The CA ROOT private key is the cluster's crown jewel — anyone holding it can
# mint any node identity and forge the whole mTLS + node-token trust. Keep it in a
# SEPARATE, more-protected directory so it never lands in the secret-mount glob
# (the deployable Secret is only ca.crt / tls.crt / tls.key). Move ca-private/ to
# offline storage immediately after issuance.
CA_DIR="ca-private"
mkdir -p "$CA_DIR"
chmod 700 "$CA_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 (private key -> ${CA_DIR}/ca.key, NOT a deployable file)"
openssl genrsa -out "${CA_DIR}/ca.key" 4096 2>/dev/null
openssl req -x509 -new -nodes -key "${CA_DIR}/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_DIR}/ca.key" -CAcreateserial \
-days 825 -sha256 -out tls.crt \
-extfile <(printf 'subjectAltName=%s\nextendedKeyUsage=serverAuth,clientAuth\n' "$SANS")
rm -f node.csr "${CA_DIR}/ca.srl"
chmod 600 "${CA_DIR}/ca.key" tls.key
echo "==> wrote DEPLOYABLE ${OUT_DIR}/{ca.crt,tls.crt,tls.key}"
echo " CA ROOT KEY at ${OUT_DIR}/${CA_DIR}/ca.key — move it to OFFLINE storage now;"
echo " it must NEVER be copied to a pod or included in the cluster Secret."
echo " grpc_tls: ca_cert=ca.crt server_cert=client_cert=tls.crt server_key=client_key=tls.key"