Let's encrypt auto-gen and auto-renew script


Since Let's Encrypt went into open beta on the 3rd of December 2015. I have decided to check it out. So far the official client doesn't support any kind of automation to help you with the process of renewing the issued certificates. The client offers few switches which help you to automate things, thanks to these switches I have automated the certificate issue and renewal process.

After the initial setup of the webserver for the domains which I use for LE certs I have made the script to automatically issue certificates from the list of domains. Format of the domain list is simple, just put the each domain on new line. The script generates LE-client friendly config and then requests the new cert. During the generation of config file for the domain it also adds unix time stamp to the config so we can easily renew our certs after certain time.

Script itself is controlled via the control variables which can be set directly inside the script. All vars are self explanatory, just fill them based on your needs. If you won't set EMAIL variable, the config file will be generated without email address.

The latest version of script can be found here.

#!/bin/bash

LE_CLIENT="/home/letsencrypt/letsencrypt-auto"
LE_ARGS="certonly --config"
CONF_FOLDER="/etc/letsencrypt/domain_conf/"
DOMAIN_LIST="/root/skripty/text_files/parked_domains.txt"
RENEW_BEFORE="60"
LOG_FILE="/root/le_cron.txt"

EMAIL=""
WEBROOT="/vz/root/202/var/www/domain_parking/public_html/"


#Generates config file for LE client
function le_domain_conf {
    echo "#Cert_last_generated: $(date +"%s")" >> ${CONF_FOLDER}${1}
    echo "rsa-key-size = 4096" >> ${CONF_FOLDER}${1}
    echo "authenticator = webroot" >> ${CONF_FOLDER}${1}
    echo "webroot-path = ${WEBROOT}" >> ${CONF_FOLDER}${1}
    echo "domains = ${1}" >> ${CONF_FOLDER}${1}
    echo "agree-tos" >> ${CONF_FOLDER}${1}
    echo "server = https://acme-v01.api.letsencrypt.org/directory" >> ${CONF_FOLDER}${1}
    echo "renew-by-default" >> ${CONF_FOLDER}${1}
    if [ -z ${EMAIL} ]
    then
        echo "register-unsafely-without-email" >> ${CONF_FOLDER}${1}
    else
        echo "email = ${EMAIL}" >> ${CONF_FOLDER}${1}
    fi
}

#Returns 0 if cert needs renewing, 1 if not.
function renew_check {
    OLD_DATE="$(grep 'Cert_last' ${CONF_FOLDER}${1} | cut -d ' ' -f2)"
    CUR_DATE="$(date +"%s")"
    DATE_DIF="$(expr ${CUR_DATE} - ${OLD_DATE})"
    RENEW_DATE="$(expr ${DATE_DIF} / 86400)"
    if [ "${RENEW_DATE}" -ge "${RENEW_BEFORE}" ]
    then
        return 0
    else
        return 1
    fi
}

for DOMAIN in $(cat ${DOMAIN_LIST})
do
    if [ -f "${CONF_FOLDER}${DOMAIN}" ]
        then
        renew_check ${DOMAIN}
        RESULT="$?"
        if [ "${RESULT}" -eq 0 ]
            then
            echo "$(date +"[%Y-%m-%d %H:%M-%S]") ${DOMAIN} needs renewing" >> ${LOG_FILE}
            OLD_DATE="$(grep 'Cert_last' ${CONF_FOLDER}${1} | cut -d ' ' -f2)"
            CUR_DATE="$(date +"%s")"
            ${LE_CLIENT} ${LE_ARGS} ${CONF_FOLDER}${DOMAIN} &> /dev/null
            LE_RESULT="$?"
            if [ "${LE_RESULT}" -eq 0 ]
                then
                echo "$(date +"[%Y-%m-%d %H:%M-%S]") ${DOMAIN} successfuly renewed, updating cert date in conf file." >> ${LOG_FILE}
                sed -i "s/$OLD_DATE/$CUR_DATE/" ${CONF_FOLDER}${DOMAIN}
            fi
        fi
    else
        echo "$(date +"[%Y-%m-%d %H:%M-%S]") ${DOMAIN} generating config." >> ${LOG_FILE}
        le_domain_conf ${DOMAIN}
        echo "$(date +"[%Y-%m-%d %H:%M-%S]") ${DOMAIN} requesting cert via LE." >> ${LOG_FILE}
        ${LE_CLIENT} ${LE_ARGS} ${CONF_FOLDER}${DOMAIN} &> /dev/null
        GEN_RESULT="$?"
        if [ "${GEN_RESULT}" -eq 0 ]
            then
            echo "$(date +"[%Y-%m-%d %H:%M-%S]") ${DOMAIN} cert generated." >> ${LOG_FILE}
        fi
    fi
done

[top]