scripts/recert
2024-05-16 09:56:22 -04:00

133 lines
2.5 KiB
Bash
Executable file

#!/usr/bin/env bash
single=0 # merge the certs into a single cert
force=0 # if to skip similariaty checks or not
quiet=0 # should i shut up?!?!? :<
cert='cert.pem' # where the public cert should go
key='cert.key' # where the private cert should go
domain='localhost' # the domain to copy certs from
usage() {
printf "usage: recert [-hsfq] [-d DOMAIN] [-c CERT] [-k KEY]\n\n"
printf "\t-h\t\tshow the help message\n"
printf "\t-s\t\tcombine the certs into a single cert\n"
printf "\t-f\t\tskip cert equal checks (force)\n"
printf "\t-q\t\tquiet output\n"
printf "\t-d DOMAIN\tthe domain name to recert\n"
printf "\t-c CERT\t\tthe destination path for the cert\n"
printf "\t-k KEY\t\tthe destination path for the key (no -s)\n"
}
hash() {
if [ -f "$1" ]; then
sha3sum "$1" | awk '{ print $1 }';
fi
}
letscert() {
certbot certonly \
--preferred-chain "ISRG Root X1" \
--key-type rsa \
--webroot --webroot-path "/var/www/html" \
-d "$1"
}
recert_log() {
if [ $quiet = 0 ]; then
printf "$*" 1>&2
fi
}
chk_command() {
if ! command -v "$1" > /dev/null; then
>&2 echo "error: command '$1' could not be found"
exit 1
fi
}
while getopts ":hsfqd:c:k:" arg > /dev/null; do
case $arg in
h)
usage
exit 0
;;
s)
single=1
;;
f)
force=1
;;
q)
quiet=1
;;
d)
domain=${OPTARG}
;;
c)
cert=${OPTARG}
;;
k)
key=${OPTARG}
;;
?)
echo "unknown option"
exit 1
;;
esac
done
chk_command "getopts"
chk_command "certbot"
chk_command "openssl"
if [ ! "$cert" = "cert.pem" ] && [ "$key" = "cert.key" ]; then
name=${cert%.*}
key="$name.key"
fi
# Step 1: make sure letsencrypt certs exist (create if not)
lets_root="/etc/letsencrypt/live"
lets_cert="$lets_root/$domain/fullchain.pem"
lets_key="$lets_root/$domain/privkey.pem"
if [ ! -f "$lets_cert" ] && [ ! -f "$lets_key" ]; then
letscert "$domain"
fi
# Step 2: make sure certs wont expire soon (create if will)
if openssl x509 -checkend 604800 -noout -in "$lets_cert" > /dev/null; then
# certificate is good, only update if forced
if [ $force = 1 ]; then
rm "$lets_root"/*
rmdir "$lets_root"
recert_log "renewing... "
letscert "$domain"
else
recert_log "up to date... "
fi
else
recert_log "renewing... "
letscert "$domain"
fi
# Step 3: store lets encrypt cert into tmp file
tmp=$(mktemp)
if [ $single = 1 ]; then
{
cat "$lets_cert";
echo;
cat "$lets_key";
} >> "$tmp"
fi
# Step 4: copy certs
recert_log "copied certs\n"
if [ $single = 1 ]; then
cp "$tmp" "$cert"
else
cp "$lets_cert" "$cert"
cp "$lets_key" "$key"
fi
# Cleanup
rm "$tmp"