Created
February 26, 2016 20:48
-
-
Save philcryer/9663b2b24a6cebc51fc2 to your computer and use it in GitHub Desktop.
auto renewal script for Let's Encrypt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 [email protected] | |
## HOSTS www.example.com | |
## EMAIL [email protected] | |
## 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment