Skip to content

Instantly share code, notes, and snippets.

@wrossmann
Created July 17, 2021 00:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrossmann/9424dd6b8c7828248948ec79eb958005 to your computer and use it in GitHub Desktop.
Save wrossmann/9424dd6b8c7828248948ec79eb958005 to your computer and use it in GitHub Desktop.
CertBot post-renew hook to update ACM
#!/bin/bash
#requirements: aws CLI v2, jq, openssl
LE_DIR=${LE_DIR:-/etc/letsencrypt}
QUIET=${QUIET:-1}
function dbg {
if [ $QUIET -eq 0 ]; then
echo $@ >&2
fi
}
function domain_to_arn() {
aws acm list-certificates | \
jq -r '.CertificateSummaryList[] | select(.DomainName == "'$1'") | .CertificateArn'
}
function get_acm_serial {
aws acm describe-certificate --certificate-arn $1 | \
jq -r '.Certificate.Serial' | \
tr -d : | tr 'a-z' 'A-Z'
}
function get_x509_serial {
openssl x509 -noout -serial -in $1 | cut -d'=' -f2
}
function verify_cert_and_chain {
openssl verify -untrusted $2 $1
}
function get_key_modulus {
openssl rsa -noout -modulus -in $1
}
function get_cert_modulus {
openssl x509 -noout -modulus -in $1
}
while getopts 'qv' o; do
case "${o}" in
q) QUIET=1 ;;
v) QUIET=0 ;;
*) exit 1 ;;
esac
done
for dir in $(find ${LE_DIR}/live -mindepth 1 -maxdepth 1 -type d); do
domain=$(basename $dir)
dbg "= $domain"
arn=$(domain_to_arn $domain)
if [ -z "$arn" ]; then
dbg "$domain not found in ACM"
dbg "Skipping Update"
continue
fi
acm_serial=$(get_acm_serial $arn)
cert_serial=$(get_x509_serial ${dir}/cert.pem)
if [ "$acm_serial" = "$cert_serial" ]; then
dbg "Local and ACM serials match for $domain: $acm_serial"
dbg "Skipping Update"
continue
fi
if [ "$(get_key_modulus ${dir}/privkey.pem)" != "$(get_cert_modulus ${dir}/cert.pem)" ]; then
dbg "Certificate and Key moduluses do not match."
dbg "Skipping Update"
continue
fi
# finally actually do the update
aws acm import-certificate --certificate-arn ${arn} \
--certificate fileb://${dir}/cert.pem \
--certificate-chain fileb://${dir}/fullchain.pem \
--private-key fileb://${dir}/privkey.pem
if [ $? -eq 0 ]; then
dbg Success
else
dbg Failure
fi
done
dbg "= done"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"acm:DescribeCertificate",
"acm:RemoveTagsFromCertificate",
"acm:GetCertificate",
"acm:AddTagsToCertificate",
"acm:ImportCertificate"
],
"Resource": [ "list", "of", "ARNs" ]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"acm:ListCertificates",
"acm:ListTagsForCertificate"
],
"Resource": "*"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment