Let’s Encrypt

For many sites, especially those run by individuals or small charities, the cost of obtaining an SSL certificate has been the main barrier to HTTPS everywhere.  Even sites that really should have been accessed via an encrypted connection, such as those where users or administrators were asked to log in with passwords that they probably also use elsewhere, were often left using plain old un-encrypted HTTP.

The importance of encryption has never been higher.  Mobile devices and laptops are ubiquitous, and with them comes the use of WiFi hot-spots.  Sniffing traffic from unsecured hotspots or setting up fake access points is child’s play.  The solution to this is HTTPS, which will authenticate that you’re connecting to the correct server and then provide end-to-end encryption of the communication.

But HTTPS only provides the guarantees that we want if the site operator obtains a signed certificate that is trusted by our web browser.  Typically this meant paying for it.  Some organizations, like CAcert, attempted to run an authority that provided free certificates.  Unfortunately they were never trusted by the major browsers, which significantly limited their utility.

Historically you also needed to worry about your site having its own IP address, but that’s now a thing of the past thanks to SNI which is supported by recent versions of all major browsers.

Fortunately we also now have a solution to the problem of having to pay for the signed certificates. The solution comes in the form of Let’s Encrypt, an organization supported by the EFF, mozilla and many others.  They are a truly free certificate authority, who issue certificates for free and use a high level of automation to keep their own costs low.  They’re currently in a “public beta” phase, but you can use them right now to obtain certificates for your website.

To obtain a certificate from Let’s Encrypt you use their script.  This can attempt to work in an entirely automated manner, assuming that you’re running a supported web server and that it can parse the server configuration correctly.  I prefer a little more control, so I use it with its “webroot” plugin.  It needs access to the web root in order to prove to the certificate authority that you’re the person who is really in control of the website.

# ./letsencrypt-auto certonly --webroot \
--webroot-path /srv/web/www.mysite.org/ \
-d mysite.org.uk -d www.mysite.org.uk

That will generate the appropriate keys and certificates and place them in /etc/letsencrypt/live/mysite.org/. Now you just need to configure your web server to offer up the new certificate. For an Apache VirtualHost (on port 443 for HTTPS) you need to add lines similar to the following:

SSLEngine on
SSLProtocol all -SSLv3 -SSLv2
SSLCipherSuite !aNULL:!eNULL:!EXP:ALL:!ADH:!LOW:!EXP:!MD5:!3DES:!RC4
SSLHonorCipherOrder Off
SSLCertificateFile /etc/letsencrypt/live/mysite.org/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mysite.org/privkey.pem
SSLCaCertificateFile /etc/letsencrypt/live/mysite.org/chain.pem

If you don’t have a webroot, perhaps because the site is entirely dynamically generated by a web application, then things will be harder. There is a manual method of obtaining certificates, but that’s not the recommended approach. Better would be to serve files from the web root if (and only if) they exist, and pass all other requests through to the web application. Using Apache this should be possible using the magic of mod_rewrite:

DocumentRoot /srv/web/mysite.org/
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f
RewriteRule ^/(.+) /$1 [QSA,L]

Finally, I should note that the certificates produced are only valid for 3 months. So you’ll want to automate their renewal, probably on a monthly basis. For example, using cron:

25 6 3 * * cd /root/letsencrypt; ./letsencrypt-auto renew

Thanks to efforts like Let’s Encrypt and standards such as SNI I hope that in the near future we really will see HTTPS everywhere. Or at the very least nearly everywhere, and certainly everywhere that asks you to log in.