#!/bin/bash # # this is going to be a rewrite of this: # https://github.com/defsdoor/letsencrypt-autorenew/blob/master/get_certificates # example file mycerts: ## EMAIL admin@example.com ## HOSTS www.example.com ## EMAIL admin@mail.example.com ## HOSTS mail.example.com ## imap.example.com pop3.example.com smtp.example.com # would like to have this script work with new setups, still using the certonly setup - I don't want the webserver down # while it's the cert(s) for the domains... LEDIR=/opt/letsencrypt CONF_FILE=/etc/letsencrypt/mycerts LEROOT=/etc/letsencrypt/live RENEW_DAYS_LEFT=8 function die { echo "$*" exit 1 } function generate { typeset EMAIL="$1" typeset HOSTS="$2" CMD="" for H in $HOSTS do CMD="$CMD -d $H" done ./letsencrypt-auto certonly --renew-by-default --agree-tos --webroot --email $EMAIL $CMD --webroot-path /var/www/content/letsencrypt } function check_same_hosts { typeset CERT="$1" typeset HOSTS="$2" CERT_HOSTS="$(get_hosts_from_cert $CERT)" SORTED_CERT_HOSTS="$(sort_hosts "$CERT_HOSTS")" SORTED_HOSTS="$(sort_hosts "$HOSTS")" if [[ "$SORTED_HOSTS" == "$SORTED_CERT_HOSTS" ]] then return 0 else return 1 fi } function check_expiring_soon { typeset CERT="$1" EXPIRY_DATE=$(date -d "$(openssl x509 -in $CERTIFICATE -text | sed '/Not After/{s/^.*: //g;p};d')" '+%Y%m%d%H%M%S') typeset RENEW_DATE=$(date -d "now +$RENEW_DAYS_LEFT days" '+%Y%m%d%H%M%S') if [[ $EXPIRY_DATE < $RENEW_DATE ]] then return 1 else return 0 fi } function sort_hosts { typeset HOSTS="$1" echo "$HOSTS" | sed -r 's/[[:blank:]]+/\n/g' | sort -u } function get_hosts_from_cert { typeset CERT=$1 openssl x509 -in $CERT -text | sed -e '/X509v3 Subject Alternative Name/,/DNS/!d;/X509v3 Subject/d;s/DNS:\([^, \n]*\)/\1/g;s/[[:blank:]]//g;s/,/ /g' } function check_update_required { typeset EMAIL="$1" typeset HOSTS="$2" typeset -i UPDATE_REQUIRED=0 set $HOSTS MAIN_HOST=$1 CERTIFICATE=$LEROOT/$MAIN_HOST/cert.pem if [[ ! -d $LEROOT/$MAIN_HOST || ! -f $CERTIFICATE ]] then echo "Update required - certificate missing" UPDATE_REQUIRED=1 else check_same_hosts "$CERTIFICATE" "$HOSTS" UPDATE_REQUIRED=$? if ((UPDATE_REQUIRED==0)) then check_expiring_soon $CERTIFICATE UPDATE_REQUIRED=$? if ((UPDATE_REQUIRED==1)) then echo "Update required - certificate expiring soon ($EXPIRY_DATE)" else echo "$MAIN_HOST - up to date" fi else DIFFERENCE=$(diff <(echo "$SORTED_HOSTS") <(echo "$SORTED_CERT_HOSTS") | egrep "^[<>]" ) echo "Update required - hosts differ $DIFFERENCE" fi fi return $UPDATE_REQUIRED } function process { typeset EMAIL="$1" typeset HOSTS=$2 if ! check_update_required "$EMAIL" "$HOSTS" then generate "$EMAIL" "$HOSTS" fi } function read_conf { while read LINE do [[ -z "$LINE" ]] && continue [[ "$LINE" = \#* ]] && continue set $LINE case "$1" in "EMAIL") [[ ! -z "$HOSTS" ]] && process "$EMAIL" "$HOSTS" HOSTS="" EMAIL=$2 ;; "HOSTS") [[ ! -z "$HOSTS" ]] && process "$EMAIL" "$HOSTS" shift HOSTS="$*" ;; *) HOSTS="$HOSTS $*" ;; esac done < $CONF_FILE process "$EMAIL" "$HOSTS" } echo "Entering $LEDIR" cd $LEDIR || die "Could not change directory into $DIR" echo "Updating from git" git pull || die "Git pull returned unexpectedly" read_conf exit