#!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail function print_help_and_exit() { printf "Usage: generate-server-certificate DOMAIN.. \n" printf "\n" printf "Arguments:\n" printf " DOMAIN..\n" printf " The domains to generate a certificate for" printf "Options:\n" printf " -H, --host\n" printf " Host where the service will run, required for sops operations\n" printf " -p, --password-path\n" printf " Path inside pass to find the ca.crt and ca.key files in\n" printf " -r, --root\n" printf " Repository root\n" exit 1 } function mk_safe() { echo "${1//./-}" } domain_names=() host= password_path= root="$(git rev-parse --show-toplevel)" while [[ $# -gt 0 ]]; do case $1 in -h | --help) print_help_and_exit ;; -H | --host) shift # past argument host=$1 shift # past value ;; -p | --password-path) shift # past argument password_path=$1 shift # past value ;; -r | --root) shift # past argument root=$1 shift # past value ;; -*) echo "Unknown option $1" print_help_and_exit ;; *) domain_names+=("$1") # save domain name shift # past argument ;; esac done if [[ -z $host ]]; then printf -- "--host required\n" print_help_and_exit elif [[ -z $password_path ]]; then printf -- "--password_path required\n" print_help_and_exit fi if [[ ${#domain_names[@]} -eq 0 ]]; then print_help_and_exit fi first_safe=$(mk_safe "${domain_names[0]}") pushd "$(mktemp -d)" cat <openssl.cnf [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] EOF for key in "${!domain_names[@]}"; do echo "DNS.$((key + 1)) = ${domain_names[$key]}" >>openssl.cnf done # Get ca.key and ca.crt from pass pass "$password_path/ca.key" >ca.key pass "$password_path/ca.crt" >ca.crt # Generate private key for certificate openssl ecparam -name prime256v1 -genkey -out server.key # Generate certificate signing request (CSR) for server certificate openssl req -new -sha256 -key server.key -out server.csr -subj "/CN=*.home" # Generate server certificate using CA openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile openssl.cnf -extensions v3_req # Copy server.crt to final destination mkdir -p "$root/secrets/pub" cp server.crt "$root/secrets/pub/${first_safe}.crt" # Safe the server key to sops server_key=$(awk -v ORS='\\n' '1' server.key) key="[\"certificate-key-${first_safe}\"] \"$server_key\"" sops --set "$key" "$root/secrets/hosts/$host/secrets.yaml" # Clean Up shred -u openssl.cnf server.key ca.crt ca.key server.crt server.csr ca.srl popd