DocsReferenceTLS & certificates

TLS & certificates

The edge terminates public TLS itself, using github.com/caddyserver/certmagic with a DNS-01 challenge to obtain and renew certificates automatically. There is no manual certbot dance and no reload step.

certmagic + DNS-01#

Wildcard certificates for *.ngstone.siteare only issuable via the DNS-01 challenge type — HTTP-01 and TLS-ALPN-01 can't issue wildcards at all. DNS-01 also means individual tunnel names never touch a Certificate Transparency log, since one wildcard cert covers every tunnel forever.

The DNS provider is github.com/libdns/cloudflare, using a scoped API token with Zone:DNS:Edit on the single zone — the only pluggable seam in the TLS stack; any other libdns provider is a one-line swap.

Pin these dependencies

Pin certmagic and libdns/cloudflare to exact versions. The libdnsv1 interface migration is a live, recurring source of "it compiled last month" breakage — this is the one dependency pair in the project where a go get -u can take the edge down.

Two certificates#

Calling certmagic.ManageSync with both *.ngstone.site and ngstone.sitereads like one multi-SAN certificate. It isn't — certmagic does not obtain multi-SAN certificates, so that call places two independent ACME orders producing two certificates with two independent renewal schedules. This is forced anyway: a wildcard cert does not match SNI ngstone.site, so the apex needs its own certificate regardless.

The apex can fail independently

If the apex order fails (rate limit, DNS hiccup), the wildcard can be perfectly healthy while public traffic looks fine — but no agent can connect, because the control plane depends on the apex cert. ngstoned performs a startup check that a valid apex cert is loadable before :4443begins accepting, and exits loudly rather than listening with a cert it can't serve. /healthz reports both certs' NotAfter separately. Both names also validate through the same _acme-challenge.ngstone.siteTXT record, so stagger their renewal windows to avoid one order's cleanup deleting the other's in-flight record.

Control-plane TLS#

Port :4443, the control plane agents dial into, is served by the apex certificate (ngstone.site), a different certificate from the public wildcard, via tls.Config.GetCertificate. Agents connect to ngstone.site:4443.

Agent verification & pinning#

The agent performs standard WebPKI validation — ServerName: "ngstone.site", system roots. An optional SPKI pin (--pin sha256/BASE64) is checked in VerifyPeerCertificate in addition to chain validation. It is off by default, since pins combined with auto-renewing certs is a footgun unless you also reuse the same key across renewals.

Agent authentication is the bearer token, not client certificates. mTLS was rejected — it adds a private CA, issuance, and rotation ceremony for a single user with zero security gain over a 256-bit token carried inside TLS.

Storage#

Certificates are cached on disk via certmagic.FileStorageso an edge restart never blocks on Let's Encrypt:

FileStorage{Path: "/var/lib/private/ngstoned/certs"} # dir mode 0700

This path is not arbitrary under systemd's DynamicUser — see Deployment & systemd.