Skip to content

Instantly share code, notes, and snippets.

@mdhowle
Last active February 28, 2021 01:48
Show Gist options
  • Select an option

  • Save mdhowle/78b304c1437e914ee14047ea6c8cb1fe to your computer and use it in GitHub Desktop.

Select an option

Save mdhowle/78b304c1437e914ee14047ea6c8cb1fe to your computer and use it in GitHub Desktop.
Script to automate obtaining Let's Encrypt certificate with certbot using Linode DNS API
#!/bin/sh
CERTBOT_LINODE_KEY="${CERTBOT_LINODE_KEY}"
CERTBOT_EMAIL="${CERTBOT_EMAIL}"
CERTBOT_VENV=/var/cache/virtualenvs/certbot
CERTBOT_UNDO=0
CERTBOT_USE_VENV=0
CERTBOT_PROPOGATION_TIME="${CERTBOT_PROPOGATION_TIME:-1000}"
CERTBOT_DOMAIN_ARGS=""
CERTBOT_EMAIL_ARGS=""
show_help() {
script_name="$(basename "$0")"
echo "${script_name} [-e|-h] -k <api_key> -m <email> -d domain1.example.com [-d domain2.example.com]"
cat << EOF
-k key DNS API key
-d domain1 Domain to register. Can be specified multiple times
-m email Email address
-p <secs> Propogation time in seconds (default: 1000)
-e Create certbot virtualenv
-u Uninstall certbot virtualenv
-h This help
EOF
}
parse_args() {
while :; do
case $1 in
-k)
CERTBOT_LINODE_KEY="$2"
shift
;;
-d)
CERTBOT_DOMAIN_ARGS="${CERTBOT_DOMAIN_ARGS} -d $2"
shift
;;
-m)
CERTBOT_EMAIL="$2"
shift
;;
-p)
CERTBOT_PROPOGATION_TIME="$2"
shift
;;
-e)
CERTBOT_USE_VENV=1
;;
-u)
CERTBOT_UNDO=1
;;
-h)
show_help
exit 0
;;
*)
break
;;
esac
shift
done
}
check_args() {
if [ -z "$CERTBOT_LINODE_KEY" ]; then
echo "Linode key is required: -k apikey" >&2
exit 1
fi
if [ -n "$CERTBOT_EMAIL" ]; then
CERTBOT_EMAIL_ARGS="-m $CERTBOT_EMAIL"
else
echo -- "Email address is required: -m email" >&2
exit 1
fi
if [ -z "$CERTBOT_DOMAIN_ARGS" ]; then
echo "empty domain; using hostname: $(hostname -f)" >&2
CERTBOT_DOMAIN="$(hostname -f)"
# Verify if not localhost
case "$CERTBOT_DOMAIN" in
localhost.*)
echo "domain cannot be localhost" >&2
exit 1
;;
esac
# Verify proprogation time
case "$CERTBOT_PROPOGATION_TIME" in
''|*[!0-9]*)
echo "Invalid propogation time: ${CERTBOT_PROPOGATION_TIME}"
exit 1
;;
*)
;;
esac
CERTBOT_DOMAIN_ARGS="-d ${CERTBOT_DOMAIN}"
fi
}
install_prereqs() {
apt-get -qq update
apt-get -yqq install certbot
if [ "$CERTBOT_USE_VENV" -eq 1 ]; then
apt-get -yqq install virtualenv
else
apt-get -yqq install python3-dns-linode
fi
}
setup_virtualenv() {
if [ ! -d "$CERTBOT_VENV" ]; then
mkdir -p "$CERTBOT_VENV"
virtualenv -p /usr/bin/python3 "$CERTBOT_VENV"
"${CERTBOT_VENV}/bin/pip" install certbot-dns-linode
fi
}
setup_certbot() {
if [ "$CERTBOT_USE_VENV" -eq 1 ]; then
# Add diversion
dpkg-divert --add --rename --divert /usr/bin/certbot.real /usr/bin/certbot
ln -sf "${CERTBOT_VENV}/bin/certbot" /usr/bin/certbot
fi
cat > /etc/letsencrypt/linode.ini << EOF
dns_linode_key = ${CERTBOT_LINODE_KEY}
dns_linode_version = 4
EOF
chmod 0700 /etc/letsencrypt/linode.ini
}
undo_certbot() {
# Test if /usr/bin/certbot is diverted
dpkg-divert --test --rename --remove /usr/bin/certbot 2>/dev/null
DIVERT_RV="$?"
# Remove diversion
if [ -f "/usr/bin/certbot.real" ] && [ "$DIVERT_RV" -eq 2 ]; then
rm /usr/bin/certbot
dpkg-divert --rename --remove /usr/bin/certbot
fi
# Remove virtualenv
rm -rf "$CERTBOT_VENV"
}
obtain_cert() {
printf "Check back in %s seconds at %s\\n\\n" \
"${CERTBOT_PROPOGATION_TIME}" \
"$(date -d "+${CERTBOT_PROPOGATION_TIME}sec")"
certbot certonly \
-n \
--agree-tos \
"${CERTBOT_EMAIL_ARGS}" \
--dns-linode \
--dns-linode-credentials /etc/letsencrypt/linode.ini \
--dns-linode-propagation-seconds "${CERTBOT_PROPOGATION_TIME}" \
${CERTBOT_DOMAIN_ARGS}
}
parse_args "$@"
if [ -n "$CERTBOT_UNDO" ] && [ "$CERTBOT_UNDO" -eq 1 ]; then
undo_certbot
exit 0
fi
check_args
install_prereqs
if [ "$CERTBOT_USE_VENV" -eq 1 ]; then
setup_virtualenv
fi
setup_certbot
obtain_cert
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment