Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Auto renewal for Let's Encrypt Apache
#!/bin/bash
#================================================================
# Let's Encrypt renewal script for Apache on Ubuntu/Debian
# @author Erika Heidi<erika@do.co>
# Usage: ./le-renew.sh [base-domain-name]
# More info: http://do.co/1mbVihI
#================================================================
domain=$1
le_path='/opt/letsencrypt'
le_conf='/etc/letsencrypt'
exp_limit=30;
get_domain_list(){
certdomain=$1
config_file="$le_conf/renewal/$certdomain.conf"
if [ ! -f $config_file ] ; then
echo "[ERROR] The config file for the certificate $certdomain was not found."
exit 1;
fi
domains=$(grep --only-matching --perl-regex "(?<=domains \= ).*" "${config_file}")
last_char=$(echo "${domains}" | awk '{print substr($0,length,1)}')
if [ "${last_char}" = "," ]; then
domains=$(echo "${domains}" |awk '{print substr($0, 1, length-1)}')
fi
echo $domains;
}
if [ -z "$domain" ] ; then
echo "[ERROR] you must provide the domain name for the certificate renewal."
exit 1;
fi
cert_file="/etc/letsencrypt/live/$domain/fullchain.pem"
if [ ! -f $cert_file ]; then
echo "[ERROR] certificate file not found for domain $domain."
exit 1;
fi
exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s)
datenow=$(date -d "now" +%s)
days_exp=$(echo \( $exp - $datenow \) / 86400 |bc)
echo "Checking expiration date for $domain..."
if [ "$days_exp" -gt "$exp_limit" ] ; then
echo "The certificate is up to date, no need for renewal ($days_exp days left)."
exit 0;
else
echo "The certificate for $domain is about to expire soon. Starting renewal request..."
domain_list=$( get_domain_list $domain )
"$le_path"/letsencrypt-auto certonly --apache --renew-by-default --domains "${domain_list}"
echo "Restarting Apache..."
/usr/sbin/service apache2 reload
echo "Renewal process finished for domain $domain"
exit 0;
fi
@nikos

This comment has been minimized.

Show comment
Hide comment
@nikos

nikos Jan 10, 2016

Thanks for your script and your blog article.
To avoid any hickups of the webserver you could also go for a graceful restart, like replacing line 58 with:

apachectl -k graceful

nikos commented Jan 10, 2016

Thanks for your script and your blog article.
To avoid any hickups of the webserver you could also go for a graceful restart, like replacing line 58 with:

apachectl -k graceful

@bmanojlovic

This comment has been minimized.

Show comment
Hide comment
@bmanojlovic

bmanojlovic Jan 23, 2016

a bit cleaned up script and removed need for some tools
https://gist.github.com/bmanojlovic/3a42ae0c19ca34f941b8

a bit cleaned up script and removed need for some tools
https://gist.github.com/bmanojlovic/3a42ae0c19ca34f941b8

@benyanke

This comment has been minimized.

Show comment
Hide comment
@benyanke

benyanke Jan 28, 2016

Added timestamp at the top, to make logging more clear:

https://gist.github.com/benyanke/3162eecd17c859c59f88

Added timestamp at the top, to make logging more clear:

https://gist.github.com/benyanke/3162eecd17c859c59f88

@realrasengan

This comment has been minimized.

Show comment
Hide comment
@realrasengan

realrasengan Feb 27, 2016

Ubuntu 15.10 requires bc (sudo apt-get install bc)

Ubuntu 15.10 requires bc (sudo apt-get install bc)

@b-alidra

This comment has been minimized.

Show comment
Hide comment
@b-alidra

b-alidra Mar 21, 2016

@erikaheidi Thanks for your script and blog article.
Here's a combined version of @bmanojlovic and @benyanke:
https://gist.github.com/b-alidra/b28cbe0b546a45f4a76a

@erikaheidi Thanks for your script and blog article.
Here's a combined version of @bmanojlovic and @benyanke:
https://gist.github.com/b-alidra/b28cbe0b546a45f4a76a

@macdonjo

This comment has been minimized.

Show comment
Hide comment
@macdonjo

macdonjo Jun 21, 2016

I got [ERROR]: certificate file not found for domain but the actual error was to simply run it as sudo

macdonjo commented Jun 21, 2016

I got [ERROR]: certificate file not found for domain but the actual error was to simply run it as sudo

@jinformatique

This comment has been minimized.

Show comment
Hide comment
@jinformatique

jinformatique Jul 19, 2016

Hello,

When my cert is about to expire, I got this error:

The certificate for example.com is about to expire soon. Starting renewal request...
Requested domain  is not a FQDN

Hello,

When my cert is about to expire, I got this error:

The certificate for example.com is about to expire soon. Starting renewal request...
Requested domain  is not a FQDN
@mickaelmonsieur

This comment has been minimized.

Show comment
Hide comment
@mickaelmonsieur

mickaelmonsieur Jul 27, 2016

@juanito003, i have the same problem... no solution ?

@juanito003, i have the same problem... no solution ?

@kamil-maslowski

This comment has been minimized.

Show comment
Hide comment
@kamil-maslowski

kamil-maslowski Jul 27, 2016

@juanito003, and same here... any luck on fixing that?

@juanito003, and same here... any luck on fixing that?

@geraintp

This comment has been minimized.

Show comment
Hide comment
@geraintp

geraintp Aug 8, 2016

So this doesn't work anymore, by the looks of it the config_file from line 15's format has changed, and no longer contains the domain names, so the net result of the get_domain_list function is an empty string ' ' on top of that the --domains option doesn't work any more either, so line 56 that actually does the hard work wouldn't work even if it didn't have a blank where the list of domains should be..

don't really know enough about bash scripting to fix it without spending a lot of time on it, but if you take the code in line 56

"$le_path"/letsencrypt-auto certonly --apache --renew-by-default --domains "${domain_list}"

and convert it, and run the command

/etc/letsencrypt/letsencrypt-auto certonly --apache --renew-by-default -d yourdomain.com -d www.yourdomain.com

assuming /etc/letsencrypt is where you installed letsencrypt it should execute correctly, then service apache2 reload to start using the new cert.

geraintp commented Aug 8, 2016

So this doesn't work anymore, by the looks of it the config_file from line 15's format has changed, and no longer contains the domain names, so the net result of the get_domain_list function is an empty string ' ' on top of that the --domains option doesn't work any more either, so line 56 that actually does the hard work wouldn't work even if it didn't have a blank where the list of domains should be..

don't really know enough about bash scripting to fix it without spending a lot of time on it, but if you take the code in line 56

"$le_path"/letsencrypt-auto certonly --apache --renew-by-default --domains "${domain_list}"

and convert it, and run the command

/etc/letsencrypt/letsencrypt-auto certonly --apache --renew-by-default -d yourdomain.com -d www.yourdomain.com

assuming /etc/letsencrypt is where you installed letsencrypt it should execute correctly, then service apache2 reload to start using the new cert.

@kbpontius

This comment has been minimized.

Show comment
Hide comment
@kbpontius

kbpontius Aug 17, 2016

I used this script for a while and found it wasn't working either. This article really helped me:
https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-14-04

It covers starting out through settings up auto-renew, but it definitely covered all the bases for me.

I used this script for a while and found it wasn't working either. This article really helped me:
https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-14-04

It covers starting out through settings up auto-renew, but it definitely covered all the bases for me.

@sjaanus

This comment has been minimized.

Show comment
Hide comment
@sjaanus

sjaanus May 5, 2017

How does this compare to certbot for renewal? Is this script created before certbot was around? Which is the best practice today?

sjaanus commented May 5, 2017

How does this compare to certbot for renewal? Is this script created before certbot was around? Which is the best practice today?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment