2017-10-02 01:43:15 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
usage() {
|
2017-11-16 01:03:20 +01:00
|
|
|
cat <<EOF >&2
|
2018-10-20 10:11:46 +02:00
|
|
|
Usage: $0 --email=admin@example.com [--method={webroot|standalone}] \
|
puppet: Use certbot package timer, not our own cron job.
The certbot package installs its own systemd timer (and cron job,
which disabled itself if systemd is enabled) which updates
certificates. This process races with the cron job which Zulip
installs -- the only difference being that Zulip respects the
`certbot.auto_renew` setting, and that it passes the deploy hook.
This means that occasionally nginx would not be reloaded, when the
systemd timer caught the expiration first.
Remove the custom cron job and `certbot-maybe-renew` script, and
reconfigure certbot to always reload nginx after deploying, using
certbot directory hooks.
Since `certbot.auto_renew` can't have an effect, remove the setting.
In turn, this removes the need for `--no-zulip-conf` to
`setup-certbot`. `--deploy-hook` is similarly removed, as running
deploy hooks to restart nginx is now the default; pass
`--no-directory-hooks` in standalone mode to not attempt to reload
nginx. The other property of `--deploy-hook`, of skipping symlinking
into place, is given its own flog.
2021-12-08 23:44:33 +01:00
|
|
|
hostname.example.com [another.example.com]
|
2017-11-16 01:03:20 +01:00
|
|
|
EOF
|
|
|
|
exit 1
|
2017-10-02 01:43:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
|
|
|
echo "Error: This script must be run as root" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2017-11-16 00:19:54 +01:00
|
|
|
method=webroot
|
puppet: Use certbot package timer, not our own cron job.
The certbot package installs its own systemd timer (and cron job,
which disabled itself if systemd is enabled) which updates
certificates. This process races with the cron job which Zulip
installs -- the only difference being that Zulip respects the
`certbot.auto_renew` setting, and that it passes the deploy hook.
This means that occasionally nginx would not be reloaded, when the
systemd timer caught the expiration first.
Remove the custom cron job and `certbot-maybe-renew` script, and
reconfigure certbot to always reload nginx after deploying, using
certbot directory hooks.
Since `certbot.auto_renew` can't have an effect, remove the setting.
In turn, this removes the need for `--no-zulip-conf` to
`setup-certbot`. `--deploy-hook` is similarly removed, as running
deploy hooks to restart nginx is now the default; pass
`--no-directory-hooks` in standalone mode to not attempt to reload
nginx. The other property of `--deploy-hook`, of skipping symlinking
into place, is given its own flog.
2021-12-08 23:44:33 +01:00
|
|
|
args="$(getopt -o '' --long help,email:,method:,skip-symlink,agree-tos -n "$0" -- "$@")"
|
2017-10-02 01:43:15 +02:00
|
|
|
eval "set -- $args"
|
2023-01-04 21:11:33 +01:00
|
|
|
agree_tos=()
|
2017-10-02 01:43:15 +02:00
|
|
|
while true; do
|
|
|
|
case "$1" in
|
|
|
|
--email)
|
|
|
|
EMAIL="$2"
|
|
|
|
shift
|
|
|
|
shift
|
|
|
|
;;
|
2017-11-16 00:19:54 +01:00
|
|
|
--method)
|
|
|
|
method="$2"
|
|
|
|
shift
|
|
|
|
shift
|
|
|
|
;;
|
puppet: Use certbot package timer, not our own cron job.
The certbot package installs its own systemd timer (and cron job,
which disabled itself if systemd is enabled) which updates
certificates. This process races with the cron job which Zulip
installs -- the only difference being that Zulip respects the
`certbot.auto_renew` setting, and that it passes the deploy hook.
This means that occasionally nginx would not be reloaded, when the
systemd timer caught the expiration first.
Remove the custom cron job and `certbot-maybe-renew` script, and
reconfigure certbot to always reload nginx after deploying, using
certbot directory hooks.
Since `certbot.auto_renew` can't have an effect, remove the setting.
In turn, this removes the need for `--no-zulip-conf` to
`setup-certbot`. `--deploy-hook` is similarly removed, as running
deploy hooks to restart nginx is now the default; pass
`--no-directory-hooks` in standalone mode to not attempt to reload
nginx. The other property of `--deploy-hook`, of skipping symlinking
into place, is given its own flog.
2021-12-08 23:44:33 +01:00
|
|
|
--skip-symlink)
|
|
|
|
skip_symlink=1
|
2018-07-22 20:56:24 +02:00
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--agree-tos)
|
2023-01-04 21:11:33 +01:00
|
|
|
agree_tos=(--agree-tos)
|
2018-07-22 20:56:24 +02:00
|
|
|
shift
|
|
|
|
;;
|
2017-10-02 01:43:15 +02:00
|
|
|
--help)
|
|
|
|
show_help=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--)
|
2018-10-20 10:11:46 +02:00
|
|
|
shift
|
2017-10-02 01:43:15 +02:00
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2018-10-20 10:11:46 +02:00
|
|
|
# Parse the remaining arguments as Subject Alternative Names to pass to certbot
|
|
|
|
HOSTNAMES=()
|
|
|
|
for arg; do
|
|
|
|
HOSTNAMES+=(-d "$arg")
|
|
|
|
done
|
|
|
|
DOMAIN=$1
|
|
|
|
|
2017-10-02 01:43:15 +02:00
|
|
|
if [ -n "$show_help" ]; then
|
|
|
|
usage
|
|
|
|
fi
|
|
|
|
|
2018-08-03 02:14:48 +02:00
|
|
|
if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then
|
2017-11-16 01:04:54 +01:00
|
|
|
usage
|
|
|
|
fi
|
|
|
|
|
2017-11-16 00:19:54 +01:00
|
|
|
case "$method" in
|
|
|
|
standalone)
|
puppet: Use certbot package timer, not our own cron job.
The certbot package installs its own systemd timer (and cron job,
which disabled itself if systemd is enabled) which updates
certificates. This process races with the cron job which Zulip
installs -- the only difference being that Zulip respects the
`certbot.auto_renew` setting, and that it passes the deploy hook.
This means that occasionally nginx would not be reloaded, when the
systemd timer caught the expiration first.
Remove the custom cron job and `certbot-maybe-renew` script, and
reconfigure certbot to always reload nginx after deploying, using
certbot directory hooks.
Since `certbot.auto_renew` can't have an effect, remove the setting.
In turn, this removes the need for `--no-zulip-conf` to
`setup-certbot`. `--deploy-hook` is similarly removed, as running
deploy hooks to restart nginx is now the default; pass
`--no-directory-hooks` in standalone mode to not attempt to reload
nginx. The other property of `--deploy-hook`, of skipping symlinking
into place, is given its own flog.
2021-12-08 23:44:33 +01:00
|
|
|
method_args=(--standalone --no-directory-hooks)
|
2017-11-16 00:19:54 +01:00
|
|
|
;;
|
|
|
|
webroot)
|
2018-08-03 02:14:48 +02:00
|
|
|
method_args=(--webroot '--webroot-path=/var/lib/zulip/certbot-webroot/')
|
2017-11-16 00:19:54 +01:00
|
|
|
;;
|
|
|
|
*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2020-05-20 22:36:50 +02:00
|
|
|
# Check for a supported OS release.
|
|
|
|
if [ -f /etc/os-release ]; then
|
2020-10-15 04:55:57 +02:00
|
|
|
os_info="$(
|
|
|
|
. /etc/os-release
|
|
|
|
printf '%s\n' "$ID" "$ID_LIKE"
|
|
|
|
)"
|
|
|
|
{
|
|
|
|
read -r os_id
|
|
|
|
read -r os_id_like || true
|
|
|
|
} <<<"$os_info"
|
2020-05-20 22:36:50 +02:00
|
|
|
fi
|
|
|
|
|
2017-11-15 22:27:48 +01:00
|
|
|
set -x
|
|
|
|
|
2020-05-20 22:36:50 +02:00
|
|
|
case " $os_id $os_id_like " in
|
|
|
|
*' debian '*)
|
2020-09-21 22:33:39 +02:00
|
|
|
apt-get update
|
2020-05-20 22:36:50 +02:00
|
|
|
apt-get install -y certbot
|
|
|
|
;;
|
|
|
|
*' rhel '*)
|
|
|
|
yum install -y certbot
|
|
|
|
;;
|
|
|
|
esac
|
2017-10-02 01:43:15 +02:00
|
|
|
|
2018-01-22 23:42:04 +01:00
|
|
|
# We don't use --no-interactive, because certbot needs to ask the user
|
|
|
|
# to agree to the Let's Encrypt Subscriber Agreement (aka ToS).
|
|
|
|
# Passing --force-interactive suppresses a warning, but also brings up
|
|
|
|
# an annoying prompt we stifle with --no-eff-email.
|
2020-05-20 22:36:50 +02:00
|
|
|
certbot certonly "${method_args[@]}" \
|
2020-10-15 04:55:57 +02:00
|
|
|
"${HOSTNAMES[@]}" -m "$EMAIL" \
|
2023-01-04 21:11:33 +01:00
|
|
|
"${agree_tos[@]}" \
|
2020-10-15 04:55:57 +02:00
|
|
|
--force-interactive --no-eff-email
|
2017-10-02 01:43:15 +02:00
|
|
|
|
2017-11-15 00:12:26 +01:00
|
|
|
symlink_with_backup() {
|
|
|
|
if [ -e "$2" ]; then
|
|
|
|
# If the user is setting up our automatic certbot-management on a
|
|
|
|
# system that already has certs for Zulip, use some extra caution
|
|
|
|
# to keep the old certs available.
|
|
|
|
mv -f --backup=numbered "$2" "$2".setup-certbot || true
|
|
|
|
fi
|
|
|
|
ln -nsf "$1" "$2"
|
|
|
|
}
|
|
|
|
|
puppet: Use certbot package timer, not our own cron job.
The certbot package installs its own systemd timer (and cron job,
which disabled itself if systemd is enabled) which updates
certificates. This process races with the cron job which Zulip
installs -- the only difference being that Zulip respects the
`certbot.auto_renew` setting, and that it passes the deploy hook.
This means that occasionally nginx would not be reloaded, when the
systemd timer caught the expiration first.
Remove the custom cron job and `certbot-maybe-renew` script, and
reconfigure certbot to always reload nginx after deploying, using
certbot directory hooks.
Since `certbot.auto_renew` can't have an effect, remove the setting.
In turn, this removes the need for `--no-zulip-conf` to
`setup-certbot`. `--deploy-hook` is similarly removed, as running
deploy hooks to restart nginx is now the default; pass
`--no-directory-hooks` in standalone mode to not attempt to reload
nginx. The other property of `--deploy-hook`, of skipping symlinking
into place, is given its own flog.
2021-12-08 23:44:33 +01:00
|
|
|
if [ -z "$skip_symlink" ]; then
|
2018-07-22 20:56:24 +02:00
|
|
|
CERT_DIR=/etc/letsencrypt/live/"$DOMAIN"
|
|
|
|
symlink_with_backup "$CERT_DIR"/privkey.pem /etc/ssl/private/zulip.key
|
|
|
|
symlink_with_backup "$CERT_DIR"/fullchain.pem /etc/ssl/certs/zulip.combined-chain.crt
|
|
|
|
fi
|
2017-10-02 01:43:15 +02:00
|
|
|
|
2021-12-10 23:34:41 +01:00
|
|
|
# "certbot certonly" does not run deploy hooks, so reload nginx if
|
|
|
|
# need be to pick up the new certificate.
|
|
|
|
case "$method" in
|
|
|
|
webroot)
|
|
|
|
service nginx reload
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2017-10-02 01:43:15 +02:00
|
|
|
echo "Certbot SSL certificate configuration succeeded."
|