Published:

Moving Let's Encrypt certificates

Quite recently, I moved my self-hosted websites to a new server. The question was how to move them without downtime with respect to HTTPS certificates.

The problem

Why is this even a problem? Couldn't one create fresh ones on the new server?

Yes, one can do that. However, there's one problem. For certbot to request new certificates, the DNS entries already need to point to the new server's IP address.

Consequently, there is a short period between DNS pointing to the new server and the issuance of the new Let's Encrypt certificates in which users would not be able to request the website through HTTPS.

While it wouldn't have caused any annoyances for my very low-traffic websites, it wasn't perfect.

Copying over existing certificate files

The solution is to reuse the existing certificates instead of generating new ones.

What do we need to copy over?

Assuming you're on Linux (I am on Debian, instructions may vary on RedHat-based distros) and use certbot, you'll find the current certificate files (symlinks actually) in /etc/letsencrypt/live/<your-domain>/:

cert.pem
chain.pem
fullchain.pem
privkey.pem

All four symlinks point to files in /etc/letsencrypt/archive/<your-domain>. For example, cert.pem may point to a file with the path ../../archive/<your-domain>/cert25.pem.

So the first step is to copy all four files that the said symlinks currently reference on the old server over into /etc/letsencrypt/archive/<your-domain>/ on the new server.

Then, create the respective symlinks in /etc/letsencrypt/live/<your-domain>/ on the new server:

$ cd /etc/letsencrypt/live/<your-domain>/
$ ln -s ../../archive/<your-domain>/cert25.pem cert.pem

Set up renewal

I assume you know what other steps are needed (e.g., adapting the Nginx configuration, reloading it, etc.) to make your site available through HTTPS.

So, the last step is to set up the automatic renewal of the certificates.

For this, you must create a new file named <your-domain>.conf in /etc/letsencrypt/renewal/. In my case, I already had an existing file from a freshly generated cert in there. So, I copied that one and then adapted the paths in the first section of the file.

If your domain were example.com, it would look similar to this:

# renew_before_expiry = 30 days
version = 2.1.0
archive_dir = /etc/letsencrypt/archive/example.com
cert = /etc/letsencrypt/live/example.com/cert.pem
privkey = /etc/letsencrypt/live/example.com/privkey.pem
chain = /etc/letsencrypt/live/example.com/chain.pem
fullchain = /etc/letsencrypt/live/example.com/fullchain.pem

# Options used in the renewal process
[renewalparams]
account = <your-le-account-key>
authenticator = nginx
installer = nginx
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa

I've not tested it, but be careful with the account parameter. If you copy a renewal config file from the old server, I'm not sure if the account of the old server causes troubles with the certbot installation of the new server.

Conclusion

There's some advice on the web to copy over the whole /etc/letsencrypt/ directory from the older server. In my case, I had a new website for which I had already generated fresh Let's Encrypt certificates. The way outlined in this article was the most seamless in my case.

Published by Robert Möstl

« Back to Blog