81 lines
2.6 KiB
Bash
Executable file
81 lines
2.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
# 01_make_offline_root_ca.sh
|
|
#
|
|
# Purpose:
|
|
# Create an OFFLINE Root CA (private key + self-signed cert) under your sudo user's home,
|
|
# NOT inside Vault. This keeps the root key off the server/container (best practice).
|
|
#
|
|
# Output:
|
|
# /home/<deinUser>/vault/offline-root/<env>/
|
|
# - root-ca.key (0600) EC-P256, encrypted if ROOT_CA_PASSPHRASE is set
|
|
# - root-ca.pem (0644) self-signed cert
|
|
# - openssl.cnf (0644) with v3_ca section
|
|
#
|
|
# Usage:
|
|
# ./01_make_offline_root_ca.sh --env test
|
|
# ROOT_CA_PASSPHRASE='********' ./01_make_offline_root_ca.sh --env prod
|
|
#
|
|
# Security:
|
|
# - Keep root-ca.key offline and backed up safely (HSM/USB safe).
|
|
# - DO NOT copy the private key to /home/vault.
|
|
|
|
if [[ -t 1 ]]; then B=$'\e[1m'; R=$'\e[0m'; G=$'\e[32m'; Y=$'\e[33m'; E=$'\e[31m'; else B= R= G= Y= E=; fi
|
|
ok(){ echo -e "🟩 ${G}${B}$*${R}"; }; die(){ echo -e "🟥 ${E}${B}$*${R}" >&2; exit 1; }
|
|
|
|
ENV_NAME="test"
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--env) ENV_NAME="$2"; shift 2;;
|
|
-h|--help) sed -n '1,200p' "$0"; exit 0;;
|
|
*) die "Unknown arg: $1";;
|
|
esac
|
|
done
|
|
|
|
ME_HOME="$(cd ~ && pwd)"
|
|
OUTDIR="${ME_HOME}/vault/offline-root/${ENV_NAME}"
|
|
mkdir -p "${OUTDIR}"
|
|
|
|
# OpenSSL config (v3_ca)
|
|
cat > "${OUTDIR}/openssl.cnf" <<'CNF'
|
|
[ req ]
|
|
default_bits = 2048
|
|
distinguished_name = req_distinguished_name
|
|
x509_extensions = v3_ca
|
|
prompt = no
|
|
|
|
[ req_distinguished_name ]
|
|
C = CH
|
|
O = PrivSec
|
|
CN = PrivSec OFFLINE Root CA
|
|
|
|
[ v3_ca ]
|
|
basicConstraints = CA:true
|
|
keyUsage = keyCertSign, cRLSign
|
|
subjectKeyIdentifier = hash
|
|
authorityKeyIdentifier = keyid:always,issuer
|
|
CNF
|
|
|
|
# EC P-256 key (encrypted if passphrase provided)
|
|
if [[ -n "${ROOT_CA_PASSPHRASE:-}" ]]; then
|
|
(umask 077; openssl ecparam -name prime256v1 -genkey \
|
|
| openssl ec -aes256 -passout env:ROOT_CA_PASSPHRASE -out "${OUTDIR}/root-ca.key")
|
|
else
|
|
(umask 077; openssl ecparam -name prime256v1 -genkey -out "${OUTDIR}/root-ca.key")
|
|
fi
|
|
chmod 600 "${OUTDIR}/root-ca.key"
|
|
|
|
# Self-signed cert (10 years)
|
|
if [[ -n "${ROOT_CA_PASSPHRASE:-}" ]]; then
|
|
openssl req -x509 -new -nodes -key "${OUTDIR}/root-ca.key" -passin env:ROOT_CA_PASSPHRASE \
|
|
-sha256 -days 3650 -out "${OUTDIR}/root-ca.pem" -config "${OUTDIR}/openssl.cnf"
|
|
else
|
|
openssl req -x509 -new -key "${OUTDIR}/root-ca.key" \
|
|
-sha256 -days 3650 -out "${OUTDIR}/root-ca.pem" -config "${OUTDIR}/openssl.cnf"
|
|
fi
|
|
chmod 0644 "${OUTDIR}/root-ca.pem"
|
|
|
|
ok "Offline Root created at: ${OUTDIR}
|
|
- Keep ${OUTDIR}/root-ca.key SAFE and OFFLINE.
|
|
- Only the public cert (root-ca.pem) will be referenced by other scripts."
|
|
|