GUIDE · PREVIEW
GUIDE / CHA.07
source: docs/guide/chapters/07 Overlay Networking.md
Chapters

07 Overlay Networking

The Problem

The node is running, services are up (06 Init and Services). Now it needs to talk to other nodes. But the physical network is a mess: some nodes are on a home LAN behind NAT, some are VPS instances on different continents, some are on a corporate network with a firewall. They all have different IP addresses, different subnets, different routing rules.

FortrOS needs a network that:

  • Works regardless of the physical network topology
  • Encrypts all traffic between nodes
  • Gives every node a stable address that doesn't change when it moves
  • Is invisible to the physical network (no special router configuration)

This is an overlay network: a virtual network built on top of the physical one. The physical network (the underlay) carries encrypted packets between nodes. The overlay network provides a clean, flat address space where every node can reach every other node directly.

If you've used a VPN, you understand the concept: VPN creates a private network tunnel over the public internet. An overlay network is the same idea scaled to a mesh of machines.

How Overlays Work

Underlay vs Overlay

Underlay: The physical network. Ethernet, Wi-Fi, public internet. Each machine has an IP address assigned by its local network (DHCP, static, cloud provider). These addresses are unstable -- they change when machines move, when DHCP leases expire, when VMs are migrated.

Overlay: A virtual network running inside encrypted tunnels over the underlay. Each machine gets an overlay address that is stable, org-controlled, and independent of the physical network. Overlay traffic is encapsulated in encrypted underlay packets -- the physical network just sees encrypted UDP.

Node A (overlay: fd00::1)  ---[encrypted UDP]--->  Node B (overlay: fd00::2)
  |                                                   |
  | Physical: 192.168.1.10                            | Physical: 203.0.113.50
  | (home LAN, behind NAT)                            | (VPS, public IP)

The overlay sees fd00::1 talking to fd00::2. The underlay sees 192.168.1.10 sending encrypted UDP to 203.0.113.50. The physical network has no idea what's inside the packets.

WireGuard

WireGuard is the overlay protocol FortrOS uses. It's a modern VPN protocol built into the Linux kernel (since 5.6). Compared to older VPNs like OpenVPN or IPSec:

Feature WireGuard OpenVPN IPSec
Codebase ~4,000 lines ~100,000 lines ~400,000 lines
In-kernel Yes (since 5.6) No (userspace) Yes
Protocol UDP only TCP or UDP ESP/AH
Configuration Minimal (key + endpoint) Complex (certificates, config files) Very complex
Performance Near wire speed Slower (userspace) Variable
Identity Public key = identity Certificate-based Certificate or PSK

WireGuard's key insight: your public key IS your identity. No certificates, no usernames, no complex PKI. Each node has a keypair. You configure peers by their public key and endpoint (IP:port). WireGuard handles encryption, authentication, and key rotation automatically.

Why IPv6 ULA?

FortrOS uses IPv6 ULA (Unique Local Address, fd00::/8) for overlay addressing instead of IPv4 private ranges (10.x.x.x, 192.168.x.x). Why:

  • No collisions: ULA addresses are generated from a random prefix per org. The odds of two orgs generating the same prefix are astronomically low. IPv4 private ranges are shared by every home network in the world.
  • Large address space: A /48 prefix gives 2^80 addresses per org.
  • Global scope within the org: Every overlay address is unique and routable within the WireGuard mesh. No NAT needed.
  • The underlay can be anything: The physical network might be IPv4, IPv6, or dual-stack. The overlay is always IPv6 ULA regardless.

Each org generates a random /48 prefix during creation. Node overlay addresses are derived from the WireGuard public key hash, making them deterministic and collision-free.

How Others Do It

Tailscale: Managed WireGuard Mesh

Tailscale builds a WireGuard mesh using a central coordination server that handles peer discovery, NAT traversal (DERP relay servers), and key distribution. You install the Tailscale agent, authenticate, and the mesh configures itself.

Strength: Zero configuration, excellent NAT traversal, MagicDNS. Weakness: Depends on Tailscale's coordination servers (self-hosted Headscale exists but adds complexity). Your mesh topology is managed by a third party.

Nebula: Certificate-Based Overlay

Nebula (by Slack/Defined Networking) uses certificate-based identity and a lighthouse model for peer discovery. A CA issues certificates with embedded overlay IPs. Lighthouses are well-known nodes that help peers find each other.

Strength: Self-hosted, no third-party dependency. Certificate model is familiar. Weakness: Requires a CA and lighthouse infrastructure. More complex than WireGuard alone.

ZeroTier: Virtual Ethernet

ZeroTier creates a virtual Layer 2 (Ethernet) network. Nodes join a network by ID and get overlay addresses from a central controller. Traffic is end-to-end encrypted.

Strength: Layer 2 (can broadcast, multicast, ARP). Very easy to set up. Weakness: Central controller dependency. More overhead than Layer 3 (WireGuard).

The Tradeoffs

Feature Raw WireGuard Tailscale Nebula ZeroTier
Central dependency None Coordination server Lighthouse + CA Controller
Self-hosted Yes Headscale (community) Yes Yes (community)
NAT traversal Manual (endpoint config) Automatic (DERP) Lighthouse relay Automatic
Identity model Public key Public key + auth Certificate Network ID
Layer 3 (IP) 3 (IP) 3 (IP) 2 (Ethernet)
Kernel-native Yes Yes (uses WireGuard) No (userspace) No (userspace)

FortrOS uses raw WireGuard because: no central dependency (the mesh is self-coordinating via gossip), kernel-native performance, and the identity model (public key = identity) aligns with FortrOS's key-based enrollment.

How FortrOS Does It

Mesh Construction

The WireGuard mesh is built during enrollment and maintained by the maintainer:

  1. Enrollment: New node generates a WireGuard keypair. The public key becomes the node's overlay identity. The overlay address is derived from the key hash.
  2. Peer configuration: The provisioner adds the new node as a WireGuard peer on the gateway and tells the new node about existing peers.
  3. Gossip propagation: As the new node joins the gossip mesh, other nodes learn about it via CRDT state and add it as a WireGuard peer.
  4. Ongoing: The maintainer watches for CRDT membership changes and adds/removes WireGuard peers accordingly.

A key property of WireGuard: there's no "waking up" ritual. Peer configuration is just a list of public keys, allowed IPs, and endpoints. Once configured, a node can immediately send packets to any peer -- if the peer is up, WireGuard performs a Noise handshake transparently on the first packet. If the peer is down, packets are silently dropped (no error, no timeout). When the peer comes back, the next packet triggers a new handshake and traffic flows again. No session establishment ceremony, no mesh convergence delay. After a reboot, the moment WireGuard is configured with peers, the node is operational.

Gateway Discovery

The preboot needs to find the org gateway (the entry point for TLS authentication) before the overlay is up. Resolution order:

  1. Cached IP (UEFI vars or /persist) -- fastest, works offline
  2. Public DNS (org domain) -- works from anywhere with internet
  3. Local DNS (DHCP-provided) -- works on LAN without internet

DNS is discovery, not trust. The preboot pins the org CA certificate in its initramfs -- even if DNS is spoofed, the TLS connection fails because the spoofed server can't present a valid org CA-signed certificate.

Org policy controls which discovery methods are enabled. Government/opsec deployments can disable DNS entirely (cached IP only after initial provisioning).

Mesh Topology

A full mesh (every node peers with every node) is O(N^2): 100 nodes = 4,950 connections, 1,000 nodes = 499,500. This doesn't scale. Rather than imposing rigid zones with elected gateways, FortrOS uses an organic mesh where connection quality drives peer selection.

Every node maintains a set of WireGuard peers based on three tiers:

LAN neighbors: always peered. Nodes on the same local network discover each other via gossip (same-subnet detection, low latency measurement). LAN peers are cheap -- fast, high-bandwidth, no NAT. These connections are always maintained. LAN clusters emerge naturally from network proximity, not from manual zone assignment.

Lighthouses: always peered. Designated well-known nodes with high availability, public IPs, and good bandwidth. Every node peers with every lighthouse. Lighthouses serve as:

  • Gossip entry points: New and returning nodes reach the org through lighthouses first
  • Relay: Traffic between nodes that can't reach each other directly routes through a lighthouse
  • DNS-discoverable: Lighthouse IPs resolve from the org's domain. A traveling laptop on a hotel Wi-Fi finds the org by resolving DNS to a lighthouse.

Scored remote peers: maintained by quality. For nodes outside the LAN, a scoring reconciliation loop evaluates and maintains connections based on:

  • Latency (RTT via WireGuard keepalive or gossip round-trip)
  • Stability (how often does this peer disappear?)
  • NAT-friendliness (public IP vs behind NAT vs needs relay)
  • Current load (how many connections the peer is already handling)
  • Traffic demand (are we actually talking to this node?)

Stronger connections are maintained; weaker ones are dropped in favor of routing through better-connected intermediaries. Connections that carry heavy traffic are reinforced -- the scoring loop naturally establishes more direct peers between nodes that communicate frequently. If datacenter A and B talk a lot, multiple A-nodes get direct peers with multiple B-nodes, providing both shorter paths and redundancy (losing one cross-DC peer doesn't force everything through a lighthouse). Idle connections between well-connected nodes get pruned. The mesh topology adapts to actual usage patterns over time.

Connectivity obligation: A well-connected node cannot prune a peer if that peer has few or no other non-lighthouse connections. Gossip provides each node's peer count and connectivity -- if pruning a connection would leave the remote node isolated (only lighthouse paths remaining), the connection is kept regardless of its score. A datacenter node with 50 peers keeps the one lonely node in a remote office because it's that node's best path to the org. The cost to the datacenter node is negligible (one extra peer); the cost to the remote node of losing it is total (lighthouse-only fallback). The scoring loop accounts for this: "am I someone's lifeline?" is a scoring factor that overrides idle-pruning.

The result: The mesh organically adapts to the network topology. An office with 20 machines has a tight local mesh. A VPS in another country peers with lighthouses and a few stable cross-region nodes. A laptop on cellular peers with lighthouses and routes everything through them. No manual zone assignment needed -- the topology emerges from connection quality.

Scaling: Per node = LAN neighbors + lighthouses + scored remote peers. The peer budget is bounded. Nodes that can't be directly peered are reachable through lighthouses or well-connected intermediaries. The mesh handles everything from a 3-node homelab to a multinational org without configuration changes.

Bootstrap: Before metrics exist (first boot, after partition), nodes peer with lighthouses (DNS-discovered) and LAN neighbors (subnet-detected). The scored layer adds and refines remote peers as metrics accumulate. A deterministic fallback (sort candidates by public key from CRDT data) ensures every node can compute a set of peers without needing to ask anyone -- useful during partitions when lighthouses may be unreachable.

Stage Boundary

What This Stage Produces

After the overlay is up:

  • The WireGuard interface is active with the node's overlay IPv6 ULA address
  • The node can reach other org nodes via the overlay
  • All inter-node traffic is encrypted (WireGuard encryption + app-layer conn_auth on top)

What Is Handed Off

The overlay enables everything that follows:

What This Stage Does NOT Do

  • It does not handle service discovery (that's gossip, 08 Cluster Formation)
  • It does not manage cluster state (that's CRDTs, 08 Cluster Formation)
  • It does not handle NAT traversal for all cases (future: relay nodes)
  • It does not provide DNS within the overlay (future: org-internal DNS)

Further Reading

Concepts:

  • WireGuard -- The overlay protocol in detail

FortrOS implementation: