Simple Let's Encrypt on Debian/Apache
As you may have noticed, splitbrain.org is now available via HTTPS. This is possible through the awesome Let's Encrypt project which makes SSL certificates available to everyone for free.
They're doing that for a while now, but I always shied away from the hassle to set it up. The SSL certificates they issue are very short lived (90 days) to force you to automate the whole update process. They provide a client to do that but it is a large Python script with all kind of dependencies that also tries to reconfigure your webserver. I didn't like that at all, so I looked for alternatives.
I finally decided for letsencrypt.sh after reading this German blog post. With this, the setup proved to be extremely simple while still giving me full control over what exactly happens.
Here's a quick tutorial on how I setup SSL for my domains splitbrain.org and commie.io1):
Setup the letsencrypt.sh
tool in /etc/letsencrypt.sh/
2):
#> cd /etc/ #> git clone https://github.com/lukas2511/letsencrypt.sh.git #> cd letsencrypt.sh/ #> mkdir .acme-challenges #> echo 'it works' > .acme-challenges/test.txt #> chown -R www-data:www-data .acme-challenges #> echo 'CONTACT_EMAIL=andi@splitbrain.org' > config.sh
The last line creates a minimal config, just setting your email address (obviously use your own address).
The .acme-challenges
directory will be used to validate that you own the domain you're trying to certificate. For that it needs to be reachable via HTTP at each of those domains. The easiest way to achieve that with Apache is creating an alias. Simply create a /etc/apache2/conf.d/letsencrypt
file like this:
- /etc/apache2/conf.d/letsencrypt
Alias /.well-known/acme-challenge /etc/letsencrypt.sh/.acme-challenges <Directory /etc/letsencrypt.sh/.acme-challenges> Options None AllowOverride None Order allow,deny Allow from all </Directory>
Next reload the webserver then try to access the little test file we created in the setup above. Eg. for my domain http://www.splitbrain.org/.well-known/acme-challenge/test.txt should be reachable from the outside.
If it works so far, it's time to configure the domains you want certificates for. This is done in a /etc/letsencrypt.sh/domains.txt
file. Each line configures one certificate with multiple server aliases on one line. Again an example for my domains:
- ''/etc/letsencrypt.sh/domains.txt''
splitbrain.org www.splitbrain.org commie.io
Now it's time to run the letsencrypt.sh tool3):
#> ./letsencrypt.sh -c # INFO: Using main config file /etc/letsencrypt.sh/config.sh + Generating account key... + Registering account key with letsencrypt... Processing splitbrain.org with alternative names: www.splitbrain.org + Signing domains... + Creating new directory /etc/letsencrypt.sh/certs/splitbrain.org ... + Generating private key... + Generating signing request... + Requesting challenge for splitbrain.org... + Requesting challenge for www.splitbrain.org... + Responding to challenge for splitbrain.org... + Challenge is valid! + Responding to challenge for www.splitbrain.org... + Challenge is valid! + Requesting certificate... + Checking certificate... + Done! + Creating fullchain.pem... + Done! Processing commie.io + Signing domains... + Creating new directory /etc/letsencrypt.sh/certs/commie.io ... + Generating private key... + Generating signing request... + Requesting challenge for commie.io... + Responding to challenge for commie.io... + Challenge is valid! + Requesting certificate... + Checking certificate... + Done! + Creating fullchain.pem... + Done!
That's it! You now have the proper certificates in /etc/letsencrypt.sh/certs/
and can reconfigure your Apache to use them. The whole SSL setup is beyond the scope of this article, but basically your virtual hosts need something along the following lines4):
SSLEngine On SSLCertificateFile /etc/letsencrypt.sh/certs/splitbrain.org/cert.pem SSLCertificateKeyFile /etc/letsencrypt.sh/certs/splitbrain.org/privkey.pem SSLCertificateChainFile /etc/letsencrypt.sh/certs/splitbrain.org/chain.pem SSLCACertificateFile /etc/letsencrypt.sh/certs/splitbrain.org/fullchain.pem SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder on
There's two more things to do: make sure Apache reloads when certificates update and renew certificates automatically.
First create a hook.sh
file:
- /etc/letsencrypt.sh/hook.sh
#!/bin/bash if [ ${1} == "deploy_cert" ]; then echo " + Hook: Restarting Apache..." /etc/init.d/apache2 reload else echo " + Hook: Nothing to do..." fi
Then make it executable and add it to the configuration:
#> chmod 755 hook.sh #> echo 'HOOK="${BASEDIR}/hook.sh"' >> config.sh
And finally create a daily cron job (don't forget to make it executable):
- /etc/cron.daily/letsencrypt
#!/bin/sh /etc/letsencrypt.sh/letsencrypt.sh -c >/dev/null
That's it. Free, autoupdating SSL certificates. Welcome to the future