Skip to content

Commit 4a4d1ed

Browse files
feat(ssl): script for automatic ssl certificate generation
1 parent fca7352 commit 4a4d1ed

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed

ssl-gen.sh

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# -------------------------------
5+
# Load .env file if present
6+
# -------------------------------
7+
ENV_FILE=".env"
8+
if [ -f "$ENV_FILE" ]; then
9+
# Export variables defined in the .env file.
10+
# This method assumes no spaces around '=' and no quoted values.
11+
set -a
12+
source "$ENV_FILE"
13+
set +a
14+
echo "Loaded environment variables from $ENV_FILE."
15+
fi
16+
17+
# -------------------------------
18+
# Check dependencies
19+
# -------------------------------
20+
command -v openssl >/dev/null 2>&1 || { echo "Error: openssl is not installed." >&2; exit 1; }
21+
command -v keytool >/dev/null 2>&1 || { echo "Error: keytool is not installed." >&2; exit 1; }
22+
23+
# -------------------------------
24+
# Set output directory for secrets
25+
# -------------------------------
26+
OUTPUT_DIR="./secrets"
27+
if [ ! -d "$OUTPUT_DIR" ]; then
28+
echo "Creating output directory at $OUTPUT_DIR..."
29+
mkdir -p "$OUTPUT_DIR"
30+
fi
31+
32+
# -------------------------------
33+
# Get hostnames
34+
# -------------------------------
35+
while [[ -z "$HOSTNAMES" ]]; do
36+
read -p "Enter the hostname(s) (comma separated, e.g., kafka,localhost): " HOSTNAMES
37+
done
38+
39+
# -------------------------------
40+
# Prompt for passwords if not provided in .env
41+
# -------------------------------
42+
# Use CERTIFICATE_PASSWORD from .env for the CA password if set.
43+
if [ -z "$CERTIFICATE_PASSWORD" ]; then
44+
read -s -p "Enter CA (Certificate Authority) password: " CA_PASS
45+
echo
46+
else
47+
CA_PASS="$CERTIFICATE_PASSWORD"
48+
fi
49+
50+
# Use KEYSTORE_PASSWORD from .env for keystore if set.
51+
if [ -z "$KEYSTORE_PASSWORD" ]; then
52+
read -s -p "Enter keystore password: " KEYSTORE_PASS
53+
echo
54+
else
55+
KEYSTORE_PASS="$KEYSTORE_PASSWORD"
56+
fi
57+
58+
# Use TRUSTSTORE_PASSWORD from .env for truststore if set.
59+
if [ -z "$TRUSTSTORE_PASSWORD" ]; then
60+
read -s -p "Enter truststore password: " TRUSTSTORE_PASS
61+
echo
62+
else
63+
TRUSTSTORE_PASS="$TRUSTSTORE_PASSWORD"
64+
fi
65+
66+
# Always prompt for the client certificate export password
67+
read -s -p "Enter client certificate export password (for PKCS12 file): " CLIENT_PASS
68+
echo
69+
70+
# -------------------------------
71+
# Define filenames (all files will be placed in the OUTPUT_DIR)
72+
# -------------------------------
73+
CA_KEY="${OUTPUT_DIR}/ca.key"
74+
CA_CERT="${OUTPUT_DIR}/ca.crt"
75+
CLIENT_KEY="${OUTPUT_DIR}/client.key"
76+
CLIENT_CSR="${OUTPUT_DIR}/client.csr"
77+
CLIENT_CERT="${OUTPUT_DIR}/client.crt"
78+
PKCS12_FILE="${OUTPUT_DIR}/kafka.p12"
79+
KEYSTORE="${OUTPUT_DIR}/kafka.keystore.jks"
80+
TRUSTSTORE="${OUTPUT_DIR}/kafka.truststore.jks"
81+
SAN_FILE="${OUTPUT_DIR}/san.cnf"
82+
83+
# -------------------------------
84+
# Backup any existing files
85+
# -------------------------------
86+
for file in "$CA_KEY" "$CA_CERT" "$CLIENT_KEY" "$CLIENT_CSR" "$CLIENT_CERT" "$PKCS12_FILE" "$KEYSTORE" "$TRUSTSTORE"; do
87+
if [ -f "$file" ]; then
88+
mv "$file" "${file}.backup_$(date +%Y%m%d%H%M%S)"
89+
echo "Backed up existing file $file"
90+
fi
91+
done
92+
93+
# -------------------------------
94+
# Step 1: Generate CA Key and Self-Signed Certificate
95+
# -------------------------------
96+
echo "Generating CA key and self-signed certificate..."
97+
openssl genrsa -aes256 -passout pass:"$CA_PASS" -out "$CA_KEY" 4096
98+
openssl req -x509 -new -key "$CA_KEY" -days 365 -out "$CA_CERT" \
99+
-subj "/CN=Certificate Authority" -passin pass:"$CA_PASS"
100+
101+
# -------------------------------
102+
# Step 2: Generate Client Key and CSR
103+
# -------------------------------
104+
PRIMARY_HOST=$(echo "$HOSTNAMES" | cut -d',' -f1 | xargs)
105+
echo "Generating client private key and certificate signing request (CSR)..."
106+
openssl genrsa -out "$CLIENT_KEY" 4096
107+
openssl req -new -key "$CLIENT_KEY" -out "$CLIENT_CSR" -subj "/CN=${PRIMARY_HOST}"
108+
109+
# -------------------------------
110+
# Step 3: Create a SAN (Subject Alternative Names) Config File
111+
# -------------------------------
112+
echo "Creating SAN configuration file..."
113+
cat > "$SAN_FILE" <<EOF
114+
[ req ]
115+
distinguished_name = req_distinguished_name
116+
req_extensions = v3_req
117+
prompt = no
118+
119+
[ req_distinguished_name ]
120+
CN = ${PRIMARY_HOST}
121+
122+
[ v3_req ]
123+
subjectAltName = @alt_names
124+
125+
[ alt_names ]
126+
EOF
127+
128+
# Append each hostname as a DNS entry
129+
IFS=',' read -ra HOST_ARR <<< "$HOSTNAMES"
130+
i=1
131+
for host in "${HOST_ARR[@]}"; do
132+
host=$(echo "$host" | xargs) # trim spaces
133+
echo "DNS.$i = $host" >> "$SAN_FILE"
134+
((i++))
135+
done
136+
137+
# -------------------------------
138+
# Step 4: Sign the CSR with the CA Key to Generate the Client Certificate
139+
# -------------------------------
140+
echo "Signing the client CSR with the CA key to generate the client certificate..."
141+
openssl x509 -req -in "$CLIENT_CSR" -CA "$CA_CERT" -CAkey "$CA_KEY" -CAcreateserial \
142+
-out "$CLIENT_CERT" -days 365 -extfile "$SAN_FILE" -passin pass:"$CA_PASS"
143+
144+
# -------------------------------
145+
# Step 5: Create a PKCS12 File from Client Key and Certificate
146+
# -------------------------------
147+
echo "Creating PKCS12 file from client key and certificate..."
148+
openssl pkcs12 -export -in "$CLIENT_CERT" -inkey "$CLIENT_KEY" -certfile "$CA_CERT" \
149+
-name kafka -out "$PKCS12_FILE" -passout pass:"$CLIENT_PASS"
150+
151+
# -------------------------------
152+
# Step 6: Create the Java Keystore (.jks) Using keytool
153+
# -------------------------------
154+
echo "Importing PKCS12 file into Java keystore..."
155+
keytool -importkeystore \
156+
-deststorepass "$KEYSTORE_PASS" -destkeypass "$KEYSTORE_PASS" \
157+
-destkeystore "$KEYSTORE" \
158+
-srckeystore "$PKCS12_FILE" -srcstoretype PKCS12 -srcstorepass "$CLIENT_PASS" \
159+
-alias kafka
160+
161+
# -------------------------------
162+
# Step 7: Create the Java Truststore (.jks) and Import the CA Certificate
163+
# -------------------------------
164+
echo "Creating Java truststore and importing CA certificate..."
165+
keytool -import -file "$CA_CERT" -alias CARoot \
166+
-keystore "$TRUSTSTORE" -storepass "$TRUSTSTORE_PASS" -noprompt
167+
168+
# -------------------------------
169+
# Cleanup temporary files
170+
# -------------------------------
171+
rm -f "$SAN_FILE" "$CLIENT_CSR" "$PKCS12_FILE" "${OUTPUT_DIR}/ca.srl"
172+
173+
# -------------------------------
174+
# Summary of Generated Files
175+
# -------------------------------
176+
echo "----------------------------------------------"
177+
echo "Certificates and keystores created successfully in $OUTPUT_DIR!"
178+
echo "Files generated:"
179+
echo " - CA certificate: $CA_CERT"
180+
echo " - Client certificate: $CLIENT_CERT"
181+
echo " - Client private key: $CLIENT_KEY"
182+
echo " - Java keystore: $KEYSTORE"
183+
echo " - Java truststore: $TRUSTSTORE"
184+
echo "----------------------------------------------"

0 commit comments

Comments
 (0)