Let's Encrypt & Apache on Ubuntu Xenial
Apache, LetsEncrypt, Security, Sysadmin, Ubuntu
Let’s Encrypt is a free, automated, and open Certificate Authority. The service is provided by the Internet Security Research Group.
If you’re managing a Virtual Private Server and you want to enable encrypted connection to websites by means of HTTPS(SSL/TLS), Let’s Encrypt is a good choice.
Let’s Encrypt Client/Certbot
Certbot is the name of the client that deploys and manages Let’s Encrypt certificates on your server. Confusingly, depending on your system and the version you install, the client may have a different name.
Certbot on Ubuntu 16.04 Xenial
The package is called python-letsencrypt-apache
. To install:
This installs Certbot - but you’ll be using the command letsencrypt
.
Set Up a New Cert: Apache
Certbot/Letsencrypt has an Apache plugin that sets up the required Apache configuration. To run:
This triggers a ncurses dialog that prompts you to select the domains for which you’re enabling SSL. You’ll also be prompted to choose whether or not all resources should be served over HTTPS, or if the site should serve mixed content.
As part of the cert setup, existing config files in /etc/apache2/sites-available
are used to set up new configurations for port 443 - and a rewrite rule is added to the exisiting config for port 80 (HTTP traffic). Depending on the selections you make during install, the rewrite rule redirects HTTP traffic to HTTPS.
I have noticed one glitch in this process. If the existing config file already contains a rewrite rule, the amended config does not include the necessary RewriteEngine on
statement to actually activate the rewrite. You can see an example of this here:
This isn’t a disaster, but it does mean that you’ll either need to amend the config (and reload the Apache configuration) or amend the root URL in your app (or database) to reference the HTTPS address.
I always amend the app URL in any case - this means that traffic will be sent straight to HTTPS rather than being redirected.
Renew Certificate
Test renewal:
If this works, run:
let’s Encrypt suggest running this script twice per day as a cron job on a random minute in the hour. Certificates are valid for 90 days, and renewal won’t proceed unless the certificate is nearing it’s expiry date.
Add a New Site to an Existing Certificate
To achieve this, run:
…and follow the on-screen instructions. All sites on the server will be listed, and pre-selected for inclusion in the cert. You are then given an option to expand the existing certificate to include the new site. Agree to this and the new site will be added. Don’t forget to check the port 80 Apache config file if redirects are not working.
Common Name
You may end up with the wrong domain name as the common name attached to the certificate. You can force this by running:
This will result in a certifcate with the common name set to the first domain (in this case, primary-domain.com
).
Moving Servers: Client Confusion!
During a recent server upgrade, I moved Let’s Encrypt certificates to the new server. Description here. This is a fairly straightforward process, and allows sites to be migrated without downtime.
However, I experienced a problem when renewing the Certificate.
The old server (Ubuntu 14.04) was running a version of Certbot cloned from the GitHub repo (which is actually a pretty good option - it self updates every time you run it). On the new server (Ubuntu 16.04), I followed the Certbot install instructions for Ubuntu 16.04 as outlined here. This caused problems because the config file (created on the original server) was actually created by a newer version of Certbot than that found in the Ubuntu repos for 16.04. The OLD server had newer software than the NEW server.
The error:
The fix:
You could revoke the cert, remove the client, install Certbot as before and re-install the certificates. In other words, take off and nuke it from orbit (I always wanted to use that expression in a blog post). Alternatively append the following line to your renewal config files (see: /etc/letsencrypt/renewal
):
If you have a [[webroot_map]]
entry in the renewal config file, add the server line above that.
Kudos to Brad Warren for sharing this solution (ref below) in the Certbot issue tracker.
Remove Cert: The Nuclear Solution
Move into /etc/letsencrypt
and remove everything apart from the accounts
directory:
Disable the SSL enabled sites by running:
Remove all Apache ssl config files from /etc/apache2/sites-available
and reload Apache:
Note: Unless you’ve removed the redirect in the port 80 virtual host directive, and/or updated your app’s home URL, your site will now be broken. Take care. You should temporarily switch the site to HTTP whilst re-issuing the certificate - I’m assuming you know how to do that.
Run:
This will reissue the certificate.
This is very much a nuclear option - there are better ways to use the letsencrypt client to amend certificates and settings.
References
- Certbot Issue, GitHub: Error with renewal conf files that no longer have a “server” entry
comments powered by Disqus