3.6 KB102 lines
Blame
1#!/usr/bin/env bash
2# Grove - Generate self-signed TLS certificates for Mononoke
3# Mononoke SLAPI and git_server require TLS. This generates a CA, server cert,
4# and client cert (for sl push mTLS).
5#
6# Usage: ./generate-certs.sh [domain-or-ip]
7#
8# Examples:
9# ./generate-certs.sh # localhost/dev only
10# ./generate-certs.sh grove.host # production hub
11# ./generate-certs.sh 203.0.113.5 # instance by IP
12
13set -euo pipefail
14
15DOMAIN_OR_IP="${1:-}"
16TLS_DIR="${GROVE_TLS_DIR:-/data/grove/tls}"
17
18mkdir -p "$TLS_DIR"
19
20echo "Generating Grove TLS certificates in $TLS_DIR..."
21
22# ── Build SAN list ─────────────────────────────────────────────────
23
24SAN_DNS=("localhost" "mononoke-slapi" "mononoke-git")
25SAN_IP=("127.0.0.1")
26
27if [[ -n "$DOMAIN_OR_IP" ]]; then
28 if [[ "$DOMAIN_OR_IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
29 SAN_IP+=("$DOMAIN_OR_IP")
30 else
31 SAN_DNS+=("$DOMAIN_OR_IP")
32 fi
33fi
34
35# Build the SAN config section
36SAN_ENTRIES=""
37for i in "${!SAN_DNS[@]}"; do
38 SAN_ENTRIES+="DNS.$((i + 1)) = ${SAN_DNS[$i]}"$'\n'
39done
40for i in "${!SAN_IP[@]}"; do
41 SAN_ENTRIES+="IP.$((i + 1)) = ${SAN_IP[$i]}"$'\n'
42done
43
44# ── CA ─────────────────────────────────────────────────────────────
45
46openssl genrsa -out "$TLS_DIR/ca.key" 4096 2>/dev/null
47openssl req -new -x509 -key "$TLS_DIR/ca.key" \
48 -out "$TLS_DIR/ca.crt" -days 3650 \
49 -subj "/CN=Grove CA/O=Letterpress Labs" 2>/dev/null
50
51# ── Server cert ────────────────────────────────────────────────────
52
53openssl genrsa -out "$TLS_DIR/server.key" 4096 2>/dev/null
54openssl req -new -key "$TLS_DIR/server.key" \
55 -out "$TLS_DIR/server.csr" \
56 -subj "/CN=${DOMAIN_OR_IP:-localhost}/O=Letterpress Labs" 2>/dev/null
57
58cat > "$TLS_DIR/ext.cnf" <<EOF
59authorityKeyIdentifier=keyid,issuer
60basicConstraints=CA:FALSE
61keyUsage=digitalSignature,keyEncipherment
62extendedKeyUsage=serverAuth,clientAuth
63subjectAltName=@alt_names
64
65[alt_names]
66${SAN_ENTRIES}
67EOF
68
69openssl x509 -req -in "$TLS_DIR/server.csr" \
70 -CA "$TLS_DIR/ca.crt" -CAkey "$TLS_DIR/ca.key" \
71 -CAcreateserial -out "$TLS_DIR/server.crt" \
72 -days 3650 -extfile "$TLS_DIR/ext.cnf" 2>/dev/null
73
74# ── Client cert (for sl push mTLS) ────────────────────────────────
75
76openssl genrsa -out "$TLS_DIR/client.key" 4096 2>/dev/null
77openssl req -new -key "$TLS_DIR/client.key" \
78 -out "$TLS_DIR/client.csr" \
79 -subj "/CN=grove-client/O=Letterpress Labs" 2>/dev/null
80
81openssl x509 -req -in "$TLS_DIR/client.csr" \
82 -CA "$TLS_DIR/ca.crt" -CAkey "$TLS_DIR/ca.key" \
83 -CAcreateserial -out "$TLS_DIR/client.crt" \
84 -days 3650 2>/dev/null
85
86# ── Cleanup temp files ─────────────────────────────────────────────
87
88rm -f "$TLS_DIR"/*.csr "$TLS_DIR"/*.cnf "$TLS_DIR"/*.srl
89
90echo ""
91echo "Certificates generated in $TLS_DIR:"
92echo " ca.crt - Certificate Authority certificate"
93echo " ca.key - Certificate Authority private key"
94echo " server.crt - Server certificate (Mononoke SLAPI + git_server)"
95echo " server.key - Server private key"
96echo " client.crt - Client certificate (sl push mTLS)"
97echo " client.key - Client private key"
98if [[ -n "$DOMAIN_OR_IP" ]]; then
99 echo ""
100 echo "SANs: ${SAN_DNS[*]} / ${SAN_IP[*]}"
101fi
102