NOTE: This article is old, this hack is no longer necessary, as Debian includes dehydrated that makes all the work.
Free SSL certificates for everyone! the https://letsencrypt.org/ initiative backed by Akamai, Cisco, Mozilla and EFF, is going to offer free certificates. On this post I am going to explain how I have automated the process of creation and renewal of certificates, on a Debian server with a lot of virtualhosts with the minimal modification of the apache conf files.
The idea of the project is to extend the use of SSL certificates everywhere, the aproach of the project is that the process of provisioning certificates is selfprovisioned from the servers with no manual interaction, to force that the certificates expiration is 90 days, forcing sysadmins to automate the proccess.
In order to validate and sign the certificate the Let’s Encrypt CA, will use the DNS and will query your webserver for some credentials issued during the certificate generation.
Moreover your webserver will have to answer to some queries from the CA during the issue and renewal of certificates. The let’s encrypt software is able to modify your webserver setup, or can launch its own webserver, but none of these aproaches are aceptable for me, I want to have full control of the webserver, and make only controlled changes, there are a lot specific apache setups. Fortunately Let’s encrypt offer us a useful option called webroot that only need to put files on a place on your website, this allow us to create an automated script with full control of what is being done.
First at all we follow the instructions to install the letsencrypt binaries:
apt-get install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto
Let’s go, the only modification on the webserver in order to answer the challenges is this:
Alias /.well-known /var/www/html/le/.well-known
Restart apache, and then you can launch the command to issue your new certificate.
/root/.local/share/letsencrypt/bin/letsencrypt --renew-by-default -a webroot --webroot-path /var/www/html/le/ --server https://acme-v01.api.letsencrypt.org/directory --email admin@damia.net --text --agree-tos --agree-dev-preview -d eblog.damia.net auth
Then you have your certificates ready at:
/etc/letsencrypt/live/eblog.damia.net/cert.pem
/etc/letsencrypt/live/eblog.damia.net/chain.pem
/etc/letsencrypt/live/eblog.damia.net/fullchain.pem
/etc/letsencrypt/live/eblog.damia.net/privkey.pem
Then you can create a new virtualhost on port 443, with:
[...]
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/eblog.damia.net/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/eblog.damia.net/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/eblog.damia.net/fullchain.pem
[...]
Done, you have your new certificate!
We can automate all the process of creation and renewal, I have developed a script that automate some tasks like:
- Check the expire date of the certificate and renew when the remaining days are below a value
- Check that the directory for the challenge is well mapped
- Alert the admin if it is not posible to renew the certificate
You can see the code here, or you can download the file autole
#!/bin/bash
##
##
## LETS ENCRYPT AUTOMATION
##
## by Damia Soler
## Contact damia (at) damia (dot) net
## https://blog.damia.net
## https://github.com/damiadev/autole/
##
##
##==================================================
## SETUP
##
##
##
## REMAINING DAYS TO EXPIRE BEFORE RENEW
##
DAYSTORENEW=10
##
## REMAINING DAYS TO EXPIRE BEFORE ALERT
##
DAYSTOALERT=5
##
## EMAIL TO ALERT IF UNABLE TO RENEW
##
ALERTEMAIL=root@localhost
##
## EMAIL ACCOUNT ON LETS ENCRYPT
##
LEEMAIL=admin@example.com
##
WEBROOT=/www/htdocs/le/
##WEBROOT=/www/htdocs/le/$1
##
##
LEBIN=/root/.local/share/letsencrypt/bin/letsencrypt
##
CERTFILE=/etc/letsencrypt/live/$1/cert.pem
##====================================================================================
if test $1 = "--renew-all" ; then
echo Checking certificates
ls -1 /etc/letsencrypt/live|xargs -n1 $0 ;
/etc/init.d/apache2 graceful
exit ;
fi;
##====================================================================================
if test -a $CERTFILE ; then
d1=$(date -d "`openssl x509 -in $CERTFILE -text -noout|grep "Not After"|cut -c 25-`" +%s)
d2=$(date -d "now" +%s)
DAYS=` echo \( $d1 - $d2 \) / 86400 |bc `
echo -n `date` DOMAIN $1 will expire in $DAYS days " "
else
echo -n `date` DOMAIN $1 new
DAYS=$DAYSTOALERT;
fi;
if test $DAYS -lt $DAYSTORENEW ; then
echo Trying to renew ;
### PRETEST TO NOT MESS LE SERVERS IF YOU ARE NOT ANSWERING THE CHALLENGE
TESTFILE=$RANDOM
echo test> $WEBROOT/.well-known/acme-challenge/$TESTFILE
URL=http://$1/.well-known/acme-challenge/$TESTFILE
mkdir -p $WEBROOT/.well-known/acme-challenge
touch $WEBROOT/.well-known/acme-challenge/index.html
echo test> $WEBROOT/.well-known/acme-challenge/$TESTFILE
if curl --output /dev/null --silent --head --fail "$URL"; then
echo $LEBIN --renew-by-default -a webroot --webroot-path $WEBROOT --email $LEEMAIL --text --agree-tos -d $1 auth
$LEBIN --renew-by-default -a webroot --webroot-path $WEBROOT --email $LEEMAIL --text --agree-tos -d $1 auth
echo SSLEngine on
echo SSLCertificateFile /etc/letsencrypt/live/$1/cert.pem
echo SSLCertificateKeyFile /etc/letsencrypt/live/$1/privkey.pem
echo SSLCertificateChainFile /etc/letsencrypt/live/$1/fullchain.pem
else
echo "CAN NOT ACCESS THE PRE-CHALLENGE $URL PLEASE ADD ALIAS TO YOUR VIRTUALHOST CONF" ;
echo "Alias /.well-known $WEBROOT/.well-known" ;
fi
rm $WEBROOT/.well-known/acme-challenge/$TESTFILE
else
echo no close to expire ;
fi ;
if test $DAYS -lt $DAYSTOALERT ; then
echo ALERT DOMAIN $1 CERTIFICATE RENEWAL PROBLEM|mail $ALERTEMAIL ;
echo ALERT DOMAIN $1 CERTIFICATE RENEWAL PROBLEM ;
fi;
You can use
./autole www.mydomain.com
And you will have your new certificate available for this domain. (remeber to add previously the alias on apache).
And
./autole --renew-all
And all your certificates will be renewed. The idea is to add this to the crontab, and your certificates will be ready and renew automatically.