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
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
Arecord, and anAAAArecord 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 initbefore.
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
[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).