Skip to content

Instantly share code, notes, and snippets.

@mjameswh
Last active August 5, 2020 15:15
Show Gist options
  • Save mjameswh/b9e1b3fef3369c1edcac34047f91a952 to your computer and use it in GitHub Desktop.
Save mjameswh/b9e1b3fef3369c1edcac34047f91a952 to your computer and use it in GitHub Desktop.
A wrapper around the certbot-auto wrapper that ensure that required plugins are reinstalled.
#!/bin/bash
# The list of plugins to be installed
CERTBOT_PLUGINS="certbot-dns-route53"
### DO NOT MODIFY ANYTHING BELOW THIS LINE ###
# Work even if somebody does "sh thisscript.sh".
set -e
# Force the venv directory to be where we can easily find it
export VENV_PATH="/opt/eff.org/certbot/venv"
# Force certbot-auto to be where we expect it to be
export CERTBOT_AUTO="/usr/local/bin/certbot-auto-upstream"
# BEGIN SUDO EXECUTION ###############################################
#
# The following code handle self reexecution as root; it has been
# extracted from certbot-auto's code without significant modification
# (that is except from the reduction of intercepted arguments).
for arg in "$@" ; do
case "$arg" in
--help)
HELP=1;;
--quiet)
QUIET=1;;
-[!-]*)
OPTIND=1
while getopts ":hq" short_arg $arg; do
case "$short_arg" in
h)
HELP=1;;
q)
QUIET=1;;
esac
done;;
esac
done
say() {
if [ "$QUIET" != 1 ]; then
echo "$@"
fi
}
error() {
echo "$@"
}
# Support for busybox and others where there is no "command",
# but "which" instead
if command -v command > /dev/null 2>&1 ; then
export EXISTS="command -v"
elif which which > /dev/null 2>&1 ; then
export EXISTS="which"
else
error "Cannot find command nor which... please install one!"
exit 1
fi
# Certbot itself needs root access for almost all modes of operation.
# certbot-auto needs root access to bootstrap OS dependencies and install
# Certbot at a protected path so it can be safely run as root. To accomplish
# this, this script will attempt to run itself as root if it doesn't have the
# necessary privileges by using `sudo` or falling back to `su` if it is not
# available. The mechanism used to obtain root access can be set explicitly by
# setting the environment variable LE_AUTO_SUDO to 'sudo', 'su', 'su_sudo',
# 'SuSudo', or '' as used below.
# Because the parameters in `su -c` has to be a string,
# we need to properly escape it.
SuSudo() {
args=""
# This `while` loop iterates over all parameters given to this function.
# For each parameter, all `'` will be replace by `'"'"'`, and the escaped string
# will be wrapped in a pair of `'`, then appended to `$args` string
# For example, `echo "It's only 1\$\!"` will be escaped to:
# 'echo' 'It'"'"'s only 1$!'
# │ │└┼┘│
# │ │ │ └── `'s only 1$!'` the literal string
# │ │ └── `\"'\"` is a single quote (as a string)
# │ └── `'It'`, to be concatenated with the strings following it
# └── `echo` wrapped in a pair of `'`, it's totally fine for the shell command itself
while [ $# -ne 0 ]; do
args="$args'$(printf "%s" "$1" | sed -e "s/'/'\"'\"'/g")' "
shift
done
su root -c "$args"
}
# Sets the environment variable SUDO to be the name of the program or function
# to call to get root access. If this script already has root privleges, SUDO
# is set to an empty string. The value in SUDO should be run with the command
# to called with root privileges as arguments.
SetRootAuthMechanism() {
SUDO=""
if [ -n "${LE_AUTO_SUDO+x}" ]; then
case "$LE_AUTO_SUDO" in
SuSudo|su_sudo|su)
SUDO=SuSudo
;;
sudo)
SUDO="sudo -E"
;;
'')
# If we're not running with root, don't check that this script can only
# be modified by system users and groups.
NO_PERMISSIONS_CHECK=1
;;
*)
error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'."
exit 1
esac
say "Using preset root authorization mechanism '$LE_AUTO_SUDO'."
else
if test "`id -u`" -ne "0" ; then
if $EXISTS sudo 1>/dev/null 2>&1; then
SUDO="sudo -E"
else
say \"sudo\" is not available, will use \"su\" for installation steps...
SUDO=SuSudo
fi
fi
fi
}
if [ "$1" = "--cb-auto-has-root" ]; then
shift 1
else
SetRootAuthMechanism
if [ -n "$SUDO" ]; then
say "Requesting to rerun $0 with root privileges..."
$SUDO "$0" --cb-auto-has-root "$@"
exit 0
fi
fi
# END SUDO EXECUTION #################################################
# At this point, we are running as root
# Download certbot-auto if it is not already installed
if ! [[ -x "${CERTBOT_AUTO}" ]] ; then
say "Downloading certbot-auto..."
wget -q -O "${CERTBOT_AUTO}" https://dl.eff.org/certbot-auto
chmod 0755 "${CERTBOT_AUTO}"
fi
if [ "$HELP" = 1 ]; then
"${CERTBOT_AUTO}" --help "$@"
exit 0
fi
# Force certbot-auto to bootstrap or upgrade itself, but do no more
"${CERTBOT_AUTO}" --install-only "$@" | ( grep -v 'Certbot is installed.' || true )
# Check if required plugins are installed; install them if they are missing
(
cd ${VENV_PATH}
source bin/activate
for plugin in $CERTBOT_PLUGINS ; do
if ! pip show -q "$plugin" ; then
pip install "$plugin"
fi
done
deactivate
)
# Execute the actual certbot command
"${VENV_PATH}/bin/letsencrypt" "$@"
@1ci
Copy link

1ci commented Jul 26, 2020

Thank you so much for this.

You're a life saver

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment