Skip to content

Let's Encrypt TLS Certifictes

David Humphrey edited this page Dec 5, 2022 · 6 revisions

Overview

Starchart uses Let's Encrypt for our TLS Certificates.

This page collects various pieces of information related to Let's Encrypt, how we use it, and links to resources we need.

Resources

Understanding What Let's Encrypt Does and Creates

Let's Encrypt is a Certificate Authority (CA) that provides free SSL certificates to everyone, helping to keep the open web secure. We interact with Let's Encrypt in an automated way using the ACME protocol, which is implemented by various clients and libraries written in lots of different languages.

Certificates are issued for a given domain (e.g., example.com) or for a group of subodomains (e.g., www.example.com, blog.example.com, mail.example.com, etc. using the wildcard domain *.example.com). Let's Encrypt requires domain owners to prove that they control the given domain(s).

The ACME client must use (i.e., an existing) or generate a new public/private key pair in order to communicate with Let's Encrypt. The client requests that Let's Encrypt issue a certificate for the given domain(s), and Let's Encrypt responds with a set of challenges, which the client uses to prove that it controls the domain(s).

There are two types of challenges: HTTP and DNS. Because Starchart is only focused on domain names (i.e., it provides no hosting), we use a DNS Challenge. In this type of challenge, the client must take a token from Let's Encrypt and place it in a DNS TXT record at the (sub)domain, for example: _acme-challenge.domain.com. This DNS record must be publicly visible to Let's Encrypt: if we have the power to put this record on the domain's DNS, and the value matches what Let's Encrypt expects, we obviously control the domain.

Now that Let's Encrypt knows that we control the domain, and has authorized our key pair, we can request a certificate. We do this by creating a Certificate Signing Request (CSR). Among other things, the CSR includes a digital signature, our public key, and the domain name for which we are requesting a certificate.

Let's Encrypt verifies the CSR cryptographically, and if everything checks out, a new certificate is issued using the public key that was sent in the CSR. Existing certificates can also be renewed or revoked in a similar manner.

The certificate we obtain from Let's Encrypt is an X.509 Certificate (often shortened to cert). This certificate includes both our public key and a digital signature proving that Let's Encrypt signed this certificate with their own private key. The certificate includes details like the common name (i.e., domain name) for which this certificate is intended, who issued the certificate, the validity period of the certificate (they expire), etc.

We can use the certificate and our private key in various ways. Here's how you might do it in node.js:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('path/to/private/key.pem'),
  cert: fs.readFileSync('path/to/public/cert.pem'),
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello secure!\n');
}).listen(8000);

Let's Encrypt certificates expire in 90 days, and you are encouraged to renew them ~30 days before they expire. Due to rate limiting, the renewal process can take multiple attempts, so starting the process early is recommended.

A renewal is no different from requesting an initial certificate. Let's Encrypt considers a request a "renewal" if the domain name(s) match those of an existing certificate.