#!/usr/bin/env bash set -euo pipefail # === Config (you can override via env or first arg) === DOMAIN="${1:-${DOMAIN:-192.168.205.130.nip.io}}" BITS="${BITS:-4096}" DAYS_CA="${DAYS_CA:-3650}" # ~10 years for the CA DAYS_CERT="${DAYS_CERT:-397}" # keep server cert within common client limits WORKDIR="${WORKDIR:-ssl-${DOMAIN}}" echo ">> Generating Root CA and wildcard cert for domain: ${DOMAIN}" echo ">> Work directory: ${WORKDIR}" mkdir -p "${WORKDIR}" cd "${WORKDIR}" # Tighten key perms by default umask 077 # --- CA OpenSSL config --- cat > ca.cnf <<'EOF' [ ca ] default_ca = CA_default [ CA_default ] dir = . new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial private_key = $dir/ca.key.pem certificate = $dir/ca.cert.pem default_md = sha256 policy = policy_any copy_extensions = copy [ policy_any ] commonName = supplied countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional emailAddress = optional [ req ] default_bits = 4096 prompt = no default_md = sha256 x509_extensions = v3_ca distinguished_name = req_dn string_mask = utf8only [ req_dn ] CN = Example Local Root CA [ v3_ca ] basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, keyCertSign, cRLSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer EOF mkdir -p newcerts : > index.txt echo 1000 > serial # --- Generate CA key & self-signed cert (RSA-4096) --- echo ">> Creating CA key..." openssl genrsa -out ca.key.pem "${BITS}" >/dev/null 2>&1 chmod 600 ca.key.pem echo ">> Creating CA certificate..." openssl req -config ca.cnf -key ca.key.pem -new -x509 -days "${DAYS_CA}" -sha256 -out ca.cert.pem # --- Server/OpenSSL config with SAN --- cat > server.cnf <> Creating server key..." openssl genrsa -out "${DOMAIN}.key" "${BITS}" >/dev/null 2>&1 chmod 600 "${DOMAIN}.key" echo ">> Creating CSR..." openssl req -new -key "${DOMAIN}.key" -out "${DOMAIN}.csr.pem" -config server.cnf # --- Extensions for final certificate (keep SAN/EKU consistent) --- cat > cert_ext.cnf <> Signing server certificate with CA..." openssl x509 -req \ -in "${DOMAIN}.csr.pem" \ -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial \ -out "${DOMAIN}.crt" \ -days "${DAYS_CERT}" -sha256 \ -extfile cert_ext.cnf -extensions v3_server # --- Produce handy bundles --- # Leaf only (typical when client already trusts the CA) cp "${DOMAIN}.crt" "${DOMAIN}.leaf.pem" # Leaf + CA (some servers/clients expect to see the issuing cert) cat "${DOMAIN}.crt" ca.cert.pem > "${DOMAIN}.chain.pem" # Optional PFX for systems that prefer it (no password) openssl pkcs12 -export -out "${DOMAIN}.pfx" -inkey "${DOMAIN}.key" -in "${DOMAIN}.crt" -certfile ca.cert.pem -passout pass: # --- Verify --- echo ">> Verifying certificate chain..." openssl verify -CAfile ca.cert.pem "${DOMAIN}.crt" echo echo "=== Done ===" echo "Files created in ${WORKDIR}:" printf " - Root CA: ca.key.pem (KEEP SECRET), ca.cert.pem (import into trust store)\n" printf " - Server key: %s.key (KEEP SECRET)\n" "${DOMAIN}" printf " - Server cert: %s.crt\n" "${DOMAIN}" printf " - Chain: %s.chain.pem (leaf + CA)\n" "${DOMAIN}" printf " - CSR: %s.csr.pem\n" "${DOMAIN}" printf " - PFX: %s.pfx (no password)\n" "${DOMAIN}" echo echo "Tip: import ca.cert.pem into your OS/browser trust store; point your server at:" echo " key=${DOMAIN}.key" echo " cert=${DOMAIN}.crt (or ${DOMAIN}.chain.pem if it wants a chain)"