Skip to content

Published Services Architecture

A published service exposes a LAN host behind a gateway at a public HTTPS URL:

<service>.<gateway-id>.<suffix>

On dev, <suffix> is r.digilan-edge.com. Prod has its own suffix, set by relay_zone_suffix.

The traffic arrives through a relay. The relay splices it by SNI without decrypting, and the gateway terminates TLS with its own certificate. The end-to-end sequence is drawn in How It Works. The user guide is Published Services.

Prerequisite: the suffix

Nexus does relay work only when NEXUS_RELAY_ZONE_SUFFIX is set. Terraform sets it, together with the Cloudflare zone, the DNS token and the ACME settings, only when relay_zone_suffix is non-empty. When it is empty:

  • no names are published
  • no certificates are issued
  • relays get no routes
  • RequestRelay answers Unimplemented when no relay fleet is configured

What each layer does

Portal

A service is created with the publish wizard (template tpl-publish-http). It becomes an entry in the config's published_services:

Field Meaning
name Leftmost label of the URL (cam1)
scheme http or https towards the LAN host
address, port LAN target. Port 0 means the scheme's default
require_code Visitors must present an access code
label Display name
disabled Withdrawn: configured but not served. Absent means published

Publishing is a normal config change: save, apply, confirm (Config Lifecycle).

Nexus

  • Stores the service in the config.
  • On every heartbeat of the relay holding the gateway, sends an SNI route for each service that is not withdrawn: the FQDN mapped to the gateway's tunnel address on port 443.
  • When the gateway asks for a relay, writes <gateway-id>.<suffix> and *.<gateway-id>.<suffix> as A or AAAA records to the relay's address (TTL 60, unproxied). One wildcard covers every service, so adding a service needs no new record and no new certificate.
  • Brokers the gateway's certificate (GatewayDeviceService.RequestCertificate). The gateway sends a CSR. Nexus answers the dns-01 challenge in Cloudflare with its ACME account and returns the chain and a renew_after date. The certificate covers exactly the apex and the wildcard.
  • Relays code commands from the portal to the gateway (IssuePublishedCode, RevokePublishedCode, and the code list). The gateway's answer comes back through GatewayDeviceService.ReportCommandReply.

Relay

Reads the SNI from the first TLS record. If a route exists, it opens TCP to the gateway's tunnel address on port 443 and splices the two streams. If none exists, it closes the connection without a TLS alert. See Relay Architecture.

Gateway agent (internal/webproxy, internal/accesscode)

  • Runs a TLS proxy on TCP 443 with the brokered certificate. pf gets two quick rules: inbound TCP 443 to the gateway itself, and outbound from the gateway to each service's target address and port. Behind a relay, the traffic arrives over the tunnel; on site, it comes from the LAN.
  • Routes each request by Host to the service's LAN target. A name under its wildcard that is not published, or is withdrawn, gets 404.
  • Applies the access-code gate when require_code is set. A request without a valid code or session gets the code page. A valid code sets a session cookie.
  • Renews the certificate on the date nexus returned, not on its local clock.

Access codes

Codes are minted, stored and checked on the gateway, not by nexus and not by Zitadel. A visitor must be able to get in while the site's uplink, or the cloud, is down. A local check survives that; a redirect to an identity provider does not.

  1. The operator issues a code from the portal with a note and a lifetime. A lifetime of 0 means the device default, never "forever".
  2. Nexus forwards the request to the device as a command. The device mints the code, stores only its hash, and returns the code once. It cannot be shown again.
  3. Codes are listed with their note and expiry, and are revoked by grant id. A revoked code, and any session made from it, stops working from the next request on.
  4. Codes are runtime state on the device, not part of the config, so issuing or revoking one creates no config version.

Issuing needs the device to be reachable. Checking a code does not.

Withdraw and restore

Setting disabled: true on a service and applying the config does four things:

  • Nexus drops its route from the next relay heartbeat. The relay forgets the name within 30 s.
  • Agent stops serving the name, so it gets 404, and drops the access-code gate for it.
  • DNS is left alone. The gateway's wildcard still points at its relay.
  • Access codes are kept with their original expiry, so they work again when the service is restored.

disabled is the negative form so that configs written before the field existed keep their services published.

Path view

The portal's Published Services page shows each hop from the visitor to the LAN target. It joins the control plane's half (GetRelayLink) with the device's state report, and gives a reason for any unhealthy hop:

Visitor > DNS > Relay > Tunnel (rung) > Gateway :443 > LAN target

The rung is inferred from the WireGuard peer endpoint:

  • port 51820 means rung 1
  • port 443 means rung 2
  • a loopback endpoint (the local udpws socket) means rung 3

See Path View.