Skip to content

Optionally build skywire as a gokrazy appliance (VPN mesh-router image) #3557

Description

@0pcom

Track making skywire optionally buildable as a gokrazy appliance — a read-only, userland-less, single-purpose Go image — targeting the ethernet VPN mesh-router use case first (most skywire boards are wired). The normal .deb/AUR/MSI builds stay untouched; the appliance is a separate build/packaging path.

Why it fits

  • skywire is a single static Go binary; apps are subcommands — exactly gokrazy's model. The visor is a well-behaved supervised daemon.
  • The data plane is already Go-native: tun via songgao/water, and the vpn-router's DHCP+DNS is literally the vendored gokrazy router7 (pkg/vpnrouter/router7).
  • skywire autoconfig is an in-process Go subcommand, so first-boot config can run without a shell.

The remaining work is the control plane (shell-outs to ip/iptables/hostapd) plus image/kernel/board bring-up.

Phases

Phase 0 — Go-native control plane (prereq for everything)

  • 0a — ip → netlink + sysctl/proc — new pkg/vpn/netctl. Behavior-identical to ip, removes iproute2 dependency + per-command pkexec. Validated against real netlink in a rootless netns. → feat(vpn): Go-native control plane — netlink (default) + nftables firewall (tag-gated) #3556
  • 0b — iptablesgoogle/nftables (masquerade, FORWARD accept, mesh-gateway REDIRECT, TCPMSS clamp). The delicate part: the --clamp-mss-to-pmtu expression (tcp option maxseg size set rt mtu) and REDIRECT need careful translation + validation. Alternatively, an interim path bundles the nft binary in the image.

Phase 1 — Pi4 ethernet-router appliance image

  • A gok config (separate repo, mirroring apt-repo/AUR) referencing cmd/skywire as a gokrazy package.
  • Kernel with tun + nf_tables/nft_nat/nft_masq enabled.
  • First-boot config seeded to gokrazy /perm (keys + skywire.json) via in-process autoconfig.
  • Scope: ethernet-uplink + ethernet-downstream VPN router + mesh gateway (no WiFi → no hostapd). This is the first genuinely shippable skywire appliance.

Phase 2 — WiFi (deferred; the hard part)

  • No pure-Go hostapd. Bundle hostapd + wpa_supplicant (+ libnl/openssl) as image extra-files, plus the mac80211/cfg80211 stack + radio driver + firmware in the kernel. WiFi-uplink and WiFi-AP-downstream variants.

Phase 3 — Board bring-up + OTA (deferred)

  • Pi4 is first-class gokrazy (arm64); Orange Pi Prime (Allwinner) is not — needs u-boot + mainline kernel + gokrazy boot integration (requires flashing a test board).
  • Updates: gokrazy's own OTA (gok update); optionally serve gokrazy images over dmsg (fits the dmsg-served-apt-repo pattern).

Remaining control-plane shell-outs (the concrete surface)

  • ip ×27 → netlink ✅ (0a)
  • sysctl ×2 → /proc ✅ (0a)
  • iptables ×9 → nftables ⬜ (0b)
  • nmcli ×2 (vpn-client DNS) — appliance uses the mesh-gateway resolver instead; only invoked when DNSAddr is set. Minor.
  • hostapd ×2 → bundle (Phase 2)

"Optional" structure

Make netlink/nftables the default on Linux (strictly better — also fixes the pkexec flood); gate only no-elevation exec behind a build tag if needed. Keep the gok image definition in its own repo. Normal builds unaffected.

Design + surface analysis produced while implementing 0a; 0b + Phase 1 are the immediate next steps, 2 + 3 are the deferred phases needing hardware.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions