Working with Let’s Encrypt is usually straightforward, but as with any at least moderately complicated technology, it comes with its own set of problems. While I set up a production server for automatic renewals, I found myself using some practices over and over. This is a compilation of these tips and tricks.
Let’s Encrypt uses HTTP when checking for the authorization. If you redirect to HTTPS, it will follow it, but you can not configure it to use HTTPS only.
It won’t honor HSTS even on the preload list, and won’t verify the certificate itself. This makes it possible to bootstrap the process with a self-signed certificate before a valid one is issued.
As a result, it’s not enough to set up webroot authentication that works on HTTPS.
Use the autoconfigure plugins or the webroot challenge
If you use Apache/Nginx, use the autoconfigure plugins or the webroot challenge, described in the previous post. If you opt for the latter, don’t forget that you need to manually configure HTTPS.
And don’t forget to restart the server after getting a new cert.
Use the standalone auth
If you don’t use HTTP at all, use the
standalone authenticator. It works by spinning up a temporary server for the
length of the domain validation. It is the easiest solution of all, but requires port 80 to be free, which is usually
only the case for API servers.
Don’t copy the certificates
Let’s Encrypt puts the certificates to the
/etc/letsencrypt/live directory. It’s best to either symlink them or
use directly from this directory.
Focus on renewals
It’s all too easy to focus on how you get a valid certificate, but you should focus on renewals instead. For example, by using the standalone auth before firing up your service, you are all set up. But this does not cover how you renew when your app occupies port 80. In this case, either shut it down during the renewal, or get the initial cert with the app running.
Getting a certificate and renewing it should work the same
If you use a setup for the initial auth and use an entirely different one for renewals, you run the risk of some hard-to-debug problems. As the former happens immediately, while for the latter you need to wait ~60 days, it is hard to see if everything is working fine.
On the bright side, if you provided your address you’ll get an email if the renewal fails, giving you ample time to react.
Add an email to get notifications
During the registration process, you have the chance to provide an email address. If the certificate is not renewed on time, you’ll get an email reminding you to do it. In effect, you’ll know there is a problem and have a chance to react on time.
Make sure your service is restarted on renewals
Most apps don’t automatically pick up new certificates. This means that even if there is a newer one, they keep using the old one. You need to make sure that either the app is restarted, or at least is sent a signal to reload the certs.
Failing to do so results in a successful renewal, so there will be no warning emails from Let’s Encrypt, but an expired certificate presented to the users.
Use the staging server
---staging parameter can be provided for a test environment. This issues non-trusted certificates, but if
they come through, you can be sure that when you switch to the live servers your setup will continue to work.
If you request a lot of certificates, you can easily find yourself rate limited and without a valid production certificate. Do all your testing with non-production certs, and switch to live ones when you validated that everything is working properly.
Sign up for certificate issuance notifications
Certificate Transparency means all issuance must be added to CT logs. In effect, you can check all the certificates issued for your domain, and even get email alerts for new ones.
There are multiple services sending out notifications, for example Facebook operates one. Signing up helps you instantly see if an unexpected one is issued, and that might indicate a security breach.
Handle missing certificate
Make sure that you handle the bootstrapping scenario when you don’t have a valid certificate. Either use a self-signed one for the duration of the first authorization, of get the first valid one before firing up the HTTPS service.
Keep the certificates in a non-volatile volume
Store them in a volume that survives restarts and redeployments, but you don’t need to back it up. Let’s Encrypt certificates can be recreated easily, so you don’t need to worry about losing them. For example, during a server migration you can simply request new ones.
That said, you shouldn’t request a new cert after every restart. That would easily mean you find yourself rate limited during debugging an unrelated problem.
If you use Docker, use a named volume for
/etc/letsencrypt and you’re set up.