Mesh VPN: LXMF-Negotiated WireGuard Tunnels

Source: styrened/docs/mesh-vpn-architecture.md Status: Architecture / Design — Phase 1 implementation planned

Problem

Reticulum excels at identity, discovery, and reliable messaging across constrained links. It does not excel at bulk IP traffic — tunneling IP packets through RNS links wastes the bandwidth of co-located high-speed transports (WiFi, Ethernet) that could carry the same traffic at orders of magnitude higher throughput.

LXMF gives us authenticated, encrypted, store-and-forward messaging between nodes with cryptographic identity. WireGuard gives us high-performance encrypted IP tunnels. The missing piece: using one to bootstrap the other.

Core Idea

Use LXMF messages as the signaling and key exchange channel to negotiate WireGuard tunnels over whatever high-bandwidth transport is available (802.11s WiFi mesh, Ethernet, IP backhaul). Reticulum provides identity, discovery, and mutual authentication — eliminating the need for traditional PKI, IKE daemons, or manual key distribution.

The result: a mesh VPN that bootstraps itself from RNS identity alone.

Architecture

Separation of Planes

┌──────────────────────────────────────────────────────┐
│  Application Traffic (SSH, HTTP, git, monitoring)    │
├──────────────────────────────────────────────────────┤
│  WireGuard Tunnel (wg-styrene interface)             │
│  Overlay: 10.73.0.0/24                               │
├──────────────────────────────────────────────────────┤
│  802.11s Mesh or IP backhaul (Layer 2/3)             │  DATA PLANE
╞══════════════════════════════════════════════════════╡
│  Styrene Wire Protocol (tunnel negotiation msgs)     │
│  LXMF (reliable delivery, store-and-forward)         │  CONTROL PLANE
│  RNS (identity, path discovery, link encryption)     │
│  Any RNS transport (LoRa, serial, TCP, 802.11s)     │
└──────────────────────────────────────────────────────┘

Control and data planes are physically separable — the control plane can run over LoRa while the data plane runs over WiFi.

Trust Model

No certificate authority. No PKI infrastructure. No key distribution ceremony:

RNS Identity (Curve25519 key pair, already exists)
  └─ authenticates LXMF message sender
       └─ LXMF TunnelOffer carries WireGuard public key
            └─ WireGuard key trusted because sender is authenticated
                 └─ Tunnel traffic authenticated by WireGuard key

Trust is scoped by fleet membership (via hub registry) and explicit allow-lists.

Wire Protocol Extension

Tunnel negotiation uses the Styrene wire protocol (StyreneEnvelope over LXMF FIELD_CUSTOM_DATA). New message types in the reserved 0xD8–0xDF range:

TypeCodePurpose
TUNNEL_OFFER0xD8Initiate tunnel — carries WireGuard pubkey, mesh address, proposed overlay IP
TUNNEL_ACCEPT0xD9Accept tunnel — carries responder’s parameters
TUNNEL_REJECT0xDAReject with reason code (untrusted, capacity, disabled, address conflict)
TUNNEL_TEARDOWN0xDBGraceful or best-effort tunnel teardown
TUNNEL_REKEY0xDCRotate WireGuard keys with coordinated switchover
TUNNEL_KEEPALIVE0xDDHealth check with tunnel statistics
TUNNEL_TOPOLOGY0xDEShare active tunnel peer list (optional)

All payloads are msgpack-encoded, consistent with the existing wire format.

Replay Protection

Every TUNNEL_OFFER and TUNNEL_ACCEPT includes a 16-byte random nonce and timestamp. Receivers reject stale messages (>60s), cache seen nonces (120s), and drop messages from unknown identities before parsing — zero processing cost for spam.

Transport Tier Model

Nodes automatically promote and demote connections through four tiers:

TierTransportCapabilityBandwidth
3: FULLWireGuard over 802.11s/EthernetFull IP connectivity10–100+ Mbps
2: RNS_WIFIRNS Link over 802.11sLXMF messaging, file transfer, terminal1–50 Mbps
1: RNS_LORARNS over LoRaLXMF messaging only0.3–21.9 kbps
0: OFFLINENoneQueued for later delivery

Promotion is opportunistic and automatic — 802.11s peer detected → RNS link available → tunnel negotiated → full IP. Demotion is event-driven — WireGuard handshake timeout → tunnel torn down → fall back to next available transport.

Overlay IP Assignment

Three strategies, selectable per deployment:

  1. Deterministic (default): Derived from RNS identity hash via BLAKE2b. No coordination needed. Collision probability ~0.4% for 10 nodes in a /24; collisions resolved by lower-hash-wins rule.
  2. Hub-assigned: Fleet hub maintains an IP allocation table (SQLite). Nodes request addresses before offering tunnels.
  3. Manual: Static config for permanent infrastructure nodes (hubs, gateways).

Default overlay subnet: 10.73.0.0/24 (253 peers; /16 available for larger fleets).

802.11s Mesh Integration

802.11s (IEEE 802.11s-2011) provides Layer 2 mesh networking with HWMP path selection. Supported by most modern WiFi chipsets on Linux via mac80211.

  • SAE encryption: Optional WPA3-grade L2 encryption. Passphrase distributed via encrypted LXMF messages or hub CONFIG_UPDATE.
  • Channel selection: Fleet-wide config parameter. Default: channel 6 (2.4 GHz). DFS deferred.
  • Hardware: Pi 4B (BCM43455 ✓), Pi Zero 2W (BCM43436s ✓), USB RTL8812AU (varies). ESP32 uses proprietary ESP-MESH, not 802.11s — participates via gateway bridging.

Relation to Existing Features

FeatureCurrent TransportWith Active Tunnel
Terminal sessionsRNS Link via LXMFPlain SSH over overlay (optional)
File transferLXMF FILE_OFFER/CHUNKSCP/rsync over overlay
Fleet RPCLXMFHTTP API over overlay (lower latency)
git-over-styreneCustom git-remote-rnsStandard SSH/HTTPS git (overlay)

The custom transports remain valuable for Tier 1 (mesh-only) scenarios where no tunnel is available.

Implementation Plan

Phase 1: Wire Protocol + Negotiation (No 802.11s)

Two styrened nodes on the same LAN negotiate a WireGuard tunnel via LXMF:

  • TUNNEL_* message types added to StyreneMessageType enum
  • TunnelManager service: FSM (idle → offered → established → rekeying → teardown)
  • WireGuard configured via pyroute2 netlink (no shell-outs to wg/ip)
  • Tunnel capability advertised in RNS announce data
  • New dependency: pyroute2 for netlink

Phase 2: 802.11s Integration

Automatic mesh setup and tunnel promotion:

  • MeshWifiManager service: creates mesh0 interface, monitors mesh peer events
  • Tier promotion/demotion FSM connected to TunnelManager
  • SAE passphrase distribution via CONFIG_UPDATE
  • Bare-metal testing on Pi 4B fleet

Phase 3: Fleet-Wide Mesh VPN

Hub-coordinated overlay network:

  • Hub-side IP allocation (SQLite)
  • TUNNEL_TOPOLOGY exchange for mesh-wide routing
  • TUI integration: tunnel status in fleet view
  • Graceful degradation testing: kill WiFi → verify LoRa signaling continues → restore WiFi → verify tunnel re-establishes

styrene-rs Parity

Same wire protocol (0xD8–0xDE), same msgpack payloads, same negotiation FSM. Rust implementation uses wireguard-uapi, rtnetlink, and nl80211 crates. Python ↔ Rust interop is a design requirement.

Security

LayerProtectionProvider
Signaling (LXMF)End-to-end encryptionRNS Link / LXMF
Tunnel negotiationAuthenticated key exchangeRNS identity verification
WireGuard handshakeNoise IKWireGuard
Tunnel trafficChaCha20-Poly1305WireGuard
802.11s L2 (optional)SAE (WPA3)mac80211

Key rotation via TUNNEL_REKEY: default every 24 hours, configurable per fleet. Grace period for in-flight packets during switchover.

Open Questions

  1. WireGuard key derivation: Derive from RNS identity (simpler, shared blast radius) or generate independently (defense in depth)?
  2. IPv6 overlay: fe80:: + EUI-64 from RNS hash eliminates address assignment entirely.
  3. Bridge mode: Should tunnel-capable nodes with LoRa + WiFi route IP between the two? Powerful but complex.
  4. Non-Linux: 802.11s is Linux-specific. WireGuard is cross-platform. Degrade to WireGuard-over-IP on macOS/Windows?
  5. Power budget: Disable mesh WiFi on battery-powered devices?

See Also

Graph