mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 20:13:46 +00:00 
			
		
		
		
	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.
(cherry picked from commit 01e8f752a8)
		
	
		
			
				
	
	
		
			129 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env bash
 | |
| 
 | |
| set -e
 | |
| 
 | |
| usage() {
 | |
|     cat <<EOF >&2
 | |
| Usage: $0 --email=admin@example.com [--method={webroot|standalone}] \
 | |
| hostname.example.com [another.example.com]
 | |
| EOF
 | |
|     exit 1
 | |
| }
 | |
| 
 | |
| if [ "$EUID" -ne 0 ]; then
 | |
|     echo "Error: This script must be run as root" >&2
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| method=webroot
 | |
| args="$(getopt -o '' --long help,email:,method:,skip-symlink,agree-tos -n "$0" -- "$@")"
 | |
| eval "set -- $args"
 | |
| while true; do
 | |
|     case "$1" in
 | |
|         --email)
 | |
|             EMAIL="$2"
 | |
|             shift
 | |
|             shift
 | |
|             ;;
 | |
|         --method)
 | |
|             method="$2"
 | |
|             shift
 | |
|             shift
 | |
|             ;;
 | |
|         --skip-symlink)
 | |
|             skip_symlink=1
 | |
|             shift
 | |
|             ;;
 | |
|         --agree-tos)
 | |
|             agree_tos=--agree-tos
 | |
|             shift
 | |
|             ;;
 | |
|         --help)
 | |
|             show_help=1
 | |
|             shift
 | |
|             ;;
 | |
|         --)
 | |
|             shift
 | |
|             break
 | |
|             ;;
 | |
|     esac
 | |
| done
 | |
| 
 | |
| # Parse the remaining arguments as Subject Alternative Names to pass to certbot
 | |
| HOSTNAMES=()
 | |
| for arg; do
 | |
|     HOSTNAMES+=(-d "$arg")
 | |
| done
 | |
| DOMAIN=$1
 | |
| 
 | |
| if [ -n "$show_help" ]; then
 | |
|     usage
 | |
| fi
 | |
| 
 | |
| if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then
 | |
|     usage
 | |
| fi
 | |
| 
 | |
| case "$method" in
 | |
|     standalone)
 | |
|         method_args=(--standalone --no-directory-hooks)
 | |
|         ;;
 | |
|     webroot)
 | |
|         method_args=(--webroot '--webroot-path=/var/lib/zulip/certbot-webroot/')
 | |
|         ;;
 | |
|     *)
 | |
|         usage
 | |
|         ;;
 | |
| esac
 | |
| 
 | |
| # Check for a supported OS release.
 | |
| if [ -f /etc/os-release ]; then
 | |
|     os_info="$(
 | |
|         . /etc/os-release
 | |
|         printf '%s\n' "$ID" "$ID_LIKE"
 | |
|     )"
 | |
|     {
 | |
|         read -r os_id
 | |
|         read -r os_id_like || true
 | |
|     } <<<"$os_info"
 | |
| fi
 | |
| 
 | |
| set -x
 | |
| 
 | |
| case " $os_id $os_id_like " in
 | |
|     *' debian '*)
 | |
|         apt-get update
 | |
|         apt-get install -y certbot
 | |
|         ;;
 | |
|     *' rhel '*)
 | |
|         yum install -y certbot
 | |
|         ;;
 | |
| esac
 | |
| 
 | |
| # 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.
 | |
| certbot certonly "${method_args[@]}" \
 | |
|     "${HOSTNAMES[@]}" -m "$EMAIL" \
 | |
|     $agree_tos \
 | |
|     --force-interactive --no-eff-email
 | |
| 
 | |
| 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"
 | |
| }
 | |
| 
 | |
| if [ -z "$skip_symlink" ]; then
 | |
|     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
 | |
| 
 | |
| echo "Certbot SSL certificate configuration succeeded."
 |