Home / Features / Nodes
Chapter two

Nodes and the network

A node is a machine anywhere in the world that carries traffic and decides nothing. Adding one is a five-minute job; what makes it safe is that it arrives with no authority at all and is granted none.

Admin

Mint a one-time enrollment key

From the console, with a label, a use count, an expiry and — if you want the node live the moment it appears — pre-authorization. Keys are stored hashed and shown once.

Node

Enroll

The agent generates a WireGuard keypair and a TLS keypair, neither of which ever leaves the machine, and sends a certificate signing request with the enrollment key.

Master

Issue a certificate and a subnet

The key is validated and spent. The node is created in pending approval, issued a certificate from the master's own CA, and carved a tunnel subnet — a /24 out of the global pool by default, which is 253 clients on that node.

Admin

Approve it

Until you do, the node heartbeats happily and is offered to nobody. Approval materializes its address pool and puts it in the server list.

Node → Master

Mutual TLS from then on

Every call the node makes is authenticated by that client certificate, and the node's identity comes from the certificate alone. Nothing anywhere reads a node id out of a request body, so a compromised node cannot act as a different one.

Trust

Your own certificate authority, on purpose

Nodes are numerous, often addressed by bare IP, and sometimes short-lived. Getting a public certificate for each one means public DNS for each one, and every issued certificate lands in a Certificate Transparency log — which publishes your node list to anybody who cares to look.

So the master generates a CA on first start and issues every node's certificate itself. Clients pin that CA. They already trust the master implicitly — it is where they authenticate — and extending that trust to certificates it signed is coherent.

Why not the machine trust store

Because putting the node CA there would mean every public authority in that store is also trusted to mint a node. The clients trust this one root and nothing else for node connections.

Private root CA generated on first start node-fra-1 90-day cert node-sgp-1 90-day cert node-nyc-1 90-day cert Clients pin this root and trust nothing else for a node
Revocation is central and by thumbprint — no CRL to distribute, no OCSP to be down.
Lifecycle

Four states, and one of them is the useful one

Pending approval

Enrolled, inert

It has a certificate and a subnet. It is offered to nobody until an administrator says so.

Active

In the rotation

Offered to clients whose account may use it, subject to capacity and a live heartbeat.

Draining

Emptying

Keeps serving the sessions it has, hidden from every server list. This is how you take a node out for maintenance without cutting anybody off.

Disabled

Gone now

Sessions are revoked immediately rather than allowed to finish. Choosing this is choosing the abrupt option.

Offline is deliberately not a stored state. It is derived from the last heartbeat — three missed twenty-second beats and the node stops being offered — so no background job has to race heartbeats to keep a column truthful.

Linux

Kernel WireGuard, driven through wg and ip, with forwarding and NAT configured by the agent. Peer churn is a few connections a minute, so the process spawns cost nothing and the failures stay legible in the log.

Windows Server

WireGuardNT through the driver's adapter API, not the file-configured tunnel service — because reconfiguring by file means restarting the tunnel, which would drop every other client on the node each time one connects.

Data plane

Two implementations, one interface

The agent, the session manager and the reconcile loop never learn which platform is underneath. IDataPlane names nothing WireGuard-specific either, which is what leaves room for a TCP-capable transport later without touching the master, the contracts or the clients.

  • A peer is installed with exactly one /32 of AllowedIPs — anything wider would let one client source-spoof every other tunnel address on that node
  • The agent reconciles on restart: read the live peers, ask the master which sessions it should have, converge
  • Usage cursors are persisted, so an agent restart never re-reports a session's history
When things break

The master going away is a designed-for case

Nodes sit behind NAT and firewalls nobody controls, so the master never connects to a node. Every ten seconds the node sends the list of sessions it believes are live, and the master replies with the set that must die. That is the reconciliation point, and it is what makes an admin's force-disconnect land within ten seconds.

Master unreachable

New sessions fail closed. No exceptions — a ticket cannot be redeemed without the master. Established tunnels keep working for a configurable grace period, then are torn down. Set the grace to zero if that is the trade you want.

Node goes quiet

The heartbeat lapses, the master hides it and revokes its sessions, and clients are offered somewhere else.

Node up, interface down

The heartbeat says so, and the master treats it as offline for listing even though the agent is alive.

Address pool exhausted

Ticket issue fails with a distinct code and the node drops out of listings until leases free up.

Client vanishes

No WireGuard handshake within the idle timeout and the node closes the session locally, then reports it.

Add a node in an afternoon

A key from the console, one service on the machine, and one approval. The deployment guide has the exact commands.