vault-ops/infra/versions/01_make_offline_root_ca-v1.0.sh
2026-04-14 11:45:15 +07:00

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."