Skip to content

Let's encrypt

dadolhay edited this page Jan 14, 2023 · 1 revision

What is Let's encrypt?

It's a certificate authority (CA), that is:

  • recognized by most modern systems (they are added as a root ca to the key store)
  • Is free to use
  • Is completely automated

How are we using it?

Let's encrypt implements a common protocol called ACME. We can make use of a node library called acme-client to request new certificates

What do we need?

  • An accountKey, which is a PEM ancoded private key. This identifies the let's encrypt account that we connect the certificates we generate.
  • A way to list, add, and remove TXT records in the DNS server
  • An email address to use in the certificate
  • Possibly, some other details, country, state, locality, organization, organizationUnit and emailAddress
  • A way to securely store the cert, and it's expiration date

How does it work?

example adapted from official example

const generate = async ({ accountKey, domain }) => {
  /* Init client */
  const client = new acme.Client({
    directoryUrl: acme.directory.letsencrypt.production,
    accountKey,
  });

  /* Create CSR */
  const [key, csr] = await acme.crypto.createCsr({
    commonName: `*.${domain}`, // Yes, the wildcard has to be the commonName
    altNames: [domain], // But we also add the `root` or `naked` domain to the cert
    // We can also provide `country`, `state`, `locality`, `organization`, `organizationUnit` and `emailAddress` here
  });

  /* Certificate */
  const cert = await client.auto({
    csr,
    email,
    challengePriority: ["dns-01"],
    termsOfServiceAgreed: true,
    challengeCreateFn,
    challengeRemoveFn,
  });

  /* Done */
  log(`CSR:\n${csr.toString()}`);
  log(`Private key:\n${key.toString()}`);
  log(`Certificate:\n${cert.toString()}`);
};

generate({
  accountKey: await acme.crypto.createPrivateKey(),
  domain: "example.com",
  email: "[email protected]",
});

So ... How does it work again?

  • We are using a pre-existing account, by using it's PEM encoded account key. Professor will probably create this and store it in the hosting provider's secrets store
  • We are creating a CSR or certificate signing request, where we state the domain as a wildcard and as a "naked" or "root" domain as well. This means that the system will generate two challenges for us
  • It calls challengeCreateFn twice, ...actually with the exact same parameters in our case, but we have to add two TXT records with the same name
  • acme-client verifies this for us before sending the request to Let's encrypt.
  • Let's encrypt also verifies the exact same things ("dns-01" type challenge), and issues the certificate
  • The TXT records are then removed using the challengeRemoveFn, because if they were to pile up too bad (over multiple renewals), let's encrypt would start rejecting the requests.

Additional resources

Clone this wiki locally