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)
Phase 1 — Pi4 ethernet-router appliance image
Phase 2 — WiFi (deferred; the hard part)
Phase 3 — Board bring-up + OTA (deferred)
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.
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
songgao/water, and the vpn-router's DHCP+DNS is literally the vendored gokrazy router7 (pkg/vpnrouter/router7).skywire autoconfigis 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)
ip→ netlink +sysctl→/proc— newpkg/vpn/netctl. Behavior-identical toip, 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) #3556iptables→google/nftables(masquerade, FORWARD accept, mesh-gateway REDIRECT, TCPMSS clamp). The delicate part: the--clamp-mss-to-pmtuexpression (tcp option maxseg size set rt mtu) and REDIRECT need careful translation + validation. Alternatively, an interim path bundles thenftbinary in the image.Phase 1 — Pi4 ethernet-router appliance image
gokconfig (separate repo, mirroring apt-repo/AUR) referencingcmd/skywireas a gokrazy package.tun+nf_tables/nft_nat/nft_masqenabled./perm(keys +skywire.json) via in-processautoconfig.Phase 2 — WiFi (deferred; the hard part)
hostapd+wpa_supplicant(+libnl/openssl) as image extra-files, plus themac80211/cfg80211stack + radio driver + firmware in the kernel. WiFi-uplink and WiFi-AP-downstream variants.Phase 3 — Board bring-up + OTA (deferred)
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 whenDNSAddris 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
gokimage 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.