Let’s encrypt automation on Debian


letsencrypt
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:

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

    ##
    ##
    ## LETS ENCRYPT AUTOMATION
    ##
    ## by Damia Soler
    ## Contact damia (at) damia (dot) net
    ## https://blog.damia.net
    ##
    ##
    ##==================================================
    ## 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@damia.net
    ##
    WEBROOT=/var/www/html/le
    ##WEBROOT=/var/www/html/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
    $LEBIN --renew-by-default -a webroot --webroot-path $WEBROOT --server https://acme-v01.api.letsencrypt.org/directory --email $LEEMAIL --text --agree-tos --agree-dev-preview -d $1 auth
    else
    echo "CAN NOT ACCESS THE PRE-CHALLENGE $URL PLEASE ADD ALIAS TO YOUR WEBSERVER" ;
    echo "Alias /.well-known $WEBROOT/.well-known" ;
    fi
    rm $WEBROOT/.well-known/acme-challenge/$TESTFILE
    else
    echo not near 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.

    No comments :