Beta 0.2.0-beta.2, not yet for critical processes. See the roadmap
PNeX logo
Documentation of the version in development, not released yet. See the stable release (0.1.0)

Names and TLS

Get a host name and HTTPS with or without a domain — mDNS, sslip.io / nip.io, your DNS, Let's Encrypt

Browsers, the native apps, passkeys and devices all need a host name that resolves to the server, and a certificate that carries it. Browsers and apps use port 443; devices use the device endpoint (port 4443, mutual TLS with a client certificate per board), whose certificate authority they pin in their firmware, so pick the name before flashing them.

--domainExampleResolutionTLSWhen
(default)pnex.localmDNS on the LANlocal CARaspberry Pi or Linux on a home or lab LAN
sslip / nippnex-203-0-113-7.sslip.iopublic wildcard DNSLet's Encrypt (--tls cloud)public VM without a domain name
your namepnex.example.comyour DNSLet's Encrypt (--tls cloud) or local CAproduction, public access
an IP192.168.1.20nonelocal CAlast resort: passkeys are unavailable

Wildcard DNS: sslip.io and nip.io

sslip.io and nip.io are free DNS services that answer with the IP address written in the name:

pnex-203-0-113-7.sslip.io  →  203.0.113.7
pnex-203-0-113-7.nip.io    →  203.0.113.7

Their point is Let's Encrypt without DNS: a public VM named this way gets a UI certificate that every browser and app already trusts — no certificate authority to import anywhere. Devices do not use their system's trust store: they pin the root compiled into their firmware (see Let's Encrypt).

curl -fsSL https://raw.githubusercontent.com/Pnex/pnex-deploy/main/install.sh \
  | sudo bash -s -- --domain sslip --ip 203.0.113.7 --tls cloud \
      --acme-email [email protected] --admin-user [email protected]

--domain sslip (or nip) builds the name from the server's address; --ip gives the public address when the VM only sees a private one behind the provider's NAT. The installer uses the dashed form: the name stays a single label, which certificates handle best.

With a private IP, a sslip.io name still works, with the local CA: you import the CA as with .local. The only gain over a bare IP is a real host name where mDNS fails (WSL, Android before 12, DNS-over-HTTPS browsers), which keeps passkeys usable. That is why the installer uses it by default on WSL.

Things to know:

  • Clients and devices need internet DNS. A fully offline network needs mDNS or its own DNS server.
  • Some routers drop public names resolving to private addresses (DNS rebinding protection): allow-list sslip.io / nip.io in the router, or use another resolver.
  • The name contains the IP: give the server a DHCP reservation. After an address change, re-run the installer with --domain sslip and re-flash the devices.
  • To depend on no third party, delegate a subdomain of your own zone to a self-hosted sslip.io DNS server, or create a wildcard record (*.lab.example.com) pointing at the server.

Local certificate authority

In local mode the installer creates a root CA once (10 years) and renews the server certificate automatically. Each client trusts the CA once; it is served at https://<server>/api/v1/meta/ca and shown in the web app under Profile → About. Back it up: pnexctl backup includes it, and devices must be re-flashed if it is lost.

Let's Encrypt

--tls cloud replaces the local CA by Let's Encrypt for the UI (HTTP-01 challenge, renewal every 12 hours). It needs a public name and ports 80 and 443 reachable from the internet, plus 4443 from wherever the devices are.

The device endpoint (4443) serves the same certificate, so firmware pins the Let's Encrypt root (ISRG Root X1), while each board's client certificate is still issued by its organisation's CA. With the Helm chart, the device endpoint has its own private CA by default, generated once: see Kubernetes.

What devices pin

InstallCA pinned by the firmware
install.sh, --tls localthe local CA
install.sh, --tls cloudISRG Root X1 (Let's Encrypt)
Helm, defaultthe private CA the chart generates for devices.<publicHost>
Helm, deviceEdge.tls.existingSecretthe root put in deviceCa.pem

Changing the authority means rebuilding and reflashing the devices.

On this page