Menu

Certificates

Your node gets its own certificate for its domain name, and renews it by itself. This page shows how, and what to do when it can't.

On this page
  1. What the certificate is for
  2. Getting a certificate
  3. Renewal
  4. Changing the domain name
  5. Trying it out with staging
  6. Another ACME server
  7. Without a domain name

What the certificate is for

The node serves its wallet, Open Payments and its other routes over HTTPS on TCP port 443. Browsers and other wallets check that certificate against your domain name, so a node that others pay needs one they trust.

Nodes don't need it to talk to each other. Their connections, over QUIC on UDP port 443, are checked against each node's own key, with no certificate authority involved.

The HTTPS listener always has a certificate. Until the node has a real one, it makes one itself, which browsers warn about. The node keeps that one across restarts, so a browser exception you made still holds the next day.

Getting a certificate

dassie init gets the first one from Let's Encrypt, over ACME with the http-01 challenge. Before you run it:

  • your domain name must point at the server: an A record, and an AAAA record if the server has IPv6;
  • TCP port 80 must reach the node from the internet. Let's Encrypt checks your domain by fetching a file from it on port 80, and the node serves that file itself.

Then run:

$sudo dassie init

It asks for your domain name, shows Let's Encrypt's terms and asks whether you agree, and asks for an email address, which the CA may write to about your certificate. You can leave the email empty. The node then runs the order and dassie init shows each step until the certificate is installed.

Every question has a flag, so a script can run it without a terminal:

$sudo dassie init --hostname node.example.com --email you@example.com --agree-tos
Flag What it does
--hostname <name> The node's public domain name.
--email <address> The contact for the ACME account.
--agree-tos Agrees to the CA's terms without asking.
--acme-staging Uses Let's Encrypt's staging server (below).
--acme-directory <url> Uses another ACME server (below).
--skip-acme Sets the domain name and keeps the current certificate.

Without a terminal, --hostname is required, and so is --agree-tos whenever a certificate is ordered. Only the http-01 challenge is supported, so the node can't get a wildcard certificate, and it can't get one for a name that doesn't reach it on port 80.

Renewal

The node renews the certificate on its own. Once an hour it looks at the certificate, and orders a new one when:

  • 30 days or less are left before it ends;
  • it doesn't cover the node's domain name, because you changed it;
  • it still serves the certificate it made itself, though you asked for a real one with dassie init before.

If an order fails, the node waits an hour before it tries again, then twice as long after each failure, up to a day. If the CA asks it to wait longer, it does, up to a week. This keeps a node with a problem from running into Let's Encrypt's limits on failed attempts.

dassie status shows where the certificate came from and when it ends, and the last renewal's error if it failed:

$dassie status
# …
  Certificate  valid until 2027-01-12 09:30 UTC; the node renews it by itself

From 14 days before the end, it also says how long is left. If renewal keeps failing, check that your domain still points at the server and that port 80 still reaches it, then look at the node's log:

$journalctl -u dassie

Troubleshooting covers the usual causes.

Changing the domain name

Point the new name at the server, then set it:

$sudo dassie init --hostname new.example.com

When dassie init finds a certificate, it asks whether to skip ordering one. Either answer works: the node notices that its certificate no longer covers the name and orders one for the new name on its own. Until that one arrives, it serves a certificate it made itself.

A new domain name is a new address for your node's wallet and payment pointers, so tell whoever pays you.

Trying it out with staging

Let's Encrypt limits how many certificates one name can get in a week. If you're setting up and tearing down test nodes, use its staging server, whose limits are far higher:

$sudo dassie init --acme-staging

Browsers don't trust staging certificates, so they warn as they do about the node's own. When you're done testing, run this in a terminal, and answer No when it asks whether to skip the order:

$sudo dassie init --acme-directory https://acme-v02.api.letsencrypt.org/directory

The server you name is kept: once an order through it succeeds, the node renews through it too. So name Let's Encrypt's production server, as above. A plain sudo dassie init would order from staging again. Run from a script, dassie init orders nothing while the node has a certificate, so it can't leave staging.

Another ACME server

Any ACME server that offers the http-01 challenge works, such as a CA on your own network. Name its directory:

$sudo dassie init --acme-directory https://ca.example.internal/acme/directory

The directory must be an https:// URL. If the ACME server's own certificate is from a private CA, tell the node to trust that CA's root with DASSIE_ACME_CA_FILE, in a drop-in:

$sudo systemctl edit dassie.service
/etc/systemd/system/dassie.service.d/override.conf
[Service]
Environment=DASSIE_ACME_CA_FILE=/etc/dassie/acme-root.pem
$sudo systemctl restart dassie.service

With it set, the node's ACME client trusts only the roots in that file, not the system's. The node runs as a user systemd makes for it, so the file must be readable by everyone, with mode 0644, and outside /home, which the node can't see:

$sudo chmod 0644 /etc/dassie/acme-root.pem

The node reads the file when it starts, so restart it after you change the file. If it can't read the file, or a certificate in it, the node doesn't start, and says why in its log (journalctl -u dassie). A certificate from a private CA is trusted only by browsers and wallets that trust that CA, so it suits a private network, not a node others on the internet pay.

Without a domain name

A node without a domain name runs as a periphery node, and needs no certificate from a CA: it keeps the one it made. Open Payments clients reach it only through a front door it keeps as its relay, which has its own certificate. By default that is the front door at dassiepay.net, so the node is reached at <node ID>.dassiepay.net (A relay). A server without a public IP shows how to run one.

Why it works this way and how renewal is bounded (ACME).

A kopje of granite blocks against the sun, in veld grass; one dassie climbs its slab, one keeps lookout on top inside the sun, and one sleeps on the next rock; on a wide screen, a pair sits on a kopje to the left