nixos/scripts/generate-server-certificate.sh

121 lines
2.8 KiB
Bash
Raw Permalink Normal View History

2023-11-30 18:23:43 +01:00
#!/usr/bin/env bash
2023-09-21 16:05:17 +02:00
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
2023-11-30 18:23:43 +01:00
-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
;;
2023-09-21 16:05:17 +02:00
esac
done
2023-11-30 18:23:43 +01:00
if [[ -z $host ]]; then
2023-09-21 16:05:17 +02:00
printf -- "--host required\n"
print_help_and_exit
2023-11-30 18:23:43 +01:00
elif [[ -z $password_path ]]; then
2023-09-21 16:05:17 +02:00
printf -- "--password_path required\n"
print_help_and_exit
fi
2023-11-30 18:23:43 +01:00
if [[ ${#domain_names[@]} -eq 0 ]]; then
2023-09-21 16:05:17 +02:00
print_help_and_exit
fi
first_safe=$(mk_safe "${domain_names[0]}")
pushd "$(mktemp -d)"
2023-11-30 18:23:43 +01:00
cat <<EOF >openssl.cnf
2023-09-21 16:05:17 +02:00
[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
2023-11-30 18:23:43 +01:00
echo "DNS.$((key + 1)) = ${domain_names[$key]}" >>openssl.cnf
2023-09-21 16:05:17 +02:00
done
# Get ca.key and ca.crt from pass
2023-11-30 18:23:43 +01:00
pass "$password_path/ca.key" >ca.key
pass "$password_path/ca.crt" >ca.crt
2023-09-21 16:05:17 +02:00
# 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