feat: embed wireguard-go as a library, removing client-side external binary dependencies#477
Open
feat: embed wireguard-go as a library, removing client-side external binary dependencies#477
Conversation
📝 Changelog previewBelow is a preview of the Changelog that will be added to the next release. Only commit messages that follow the Conventional Commits specification will be included in the Changelog. v1.15.0 - 2026-03-27Full Changelog: v1.14.4...v1.15.0 🚀 Features
🐛 Bug Fixes
⚙️ Miscellaneous Changes |
sechmann
added a commit
that referenced
this pull request
Feb 25, 2026
- Remove custom wireguard.PrivateKey type; use wgtypes.Key everywhere - Fix ReadOrCreatePrivateKey to write/read base64 format (not raw bytes) - Fix double base64 encoding in enrollgateway.go - Replace fragile manual base64+copy with wgtypes.ParseKey in EnsurePrivateKey - Add strings.TrimSpace when reading key files to handle trailing newlines - Fix error wrapping: %v -> %w for proper errors.Is/As support - Make Configure retry loop context-aware (select on ctx.Done vs time.Sleep) - Clean up Linux interface on partial SetupInterface failure - Make IPv6 address configuration conditional on all platforms - Change GatewayRequest.WireGuardPublicKey from []byte to string
sechmann
added a commit
that referenced
this pull request
Mar 16, 2026
- Remove custom wireguard.PrivateKey type; use wgtypes.Key everywhere - Fix ReadOrCreatePrivateKey to write/read base64 format (not raw bytes) - Fix double base64 encoding in enrollgateway.go - Replace fragile manual base64+copy with wgtypes.ParseKey in EnsurePrivateKey - Add strings.TrimSpace when reading key files to handle trailing newlines - Fix error wrapping: %v -> %w for proper errors.Is/As support - Make Configure retry loop context-aware (select on ctx.Done vs time.Sleep) - Clean up Linux interface on partial SetupInterface failure - Make IPv6 address configuration conditional on all platforms - Change GatewayRequest.WireGuardPublicKey from []byte to string
cb6fb80 to
75eb38d
Compare
sechmann
added a commit
that referenced
this pull request
Mar 17, 2026
- Remove custom wireguard.PrivateKey type; use wgtypes.Key everywhere - Fix ReadOrCreatePrivateKey to write/read base64 format (not raw bytes) - Fix double base64 encoding in enrollgateway.go - Replace fragile manual base64+copy with wgtypes.ParseKey in EnsurePrivateKey - Add strings.TrimSpace when reading key files to handle trailing newlines - Fix error wrapping: %v -> %w for proper errors.Is/As support - Make Configure retry loop context-aware (select on ctx.Done vs time.Sleep) - Clean up Linux interface on partial SetupInterface failure - Make IPv6 address configuration conditional on all platforms - Change GatewayRequest.WireGuardPublicKey from []byte to string
75eb38d to
5384124
Compare
…dencies Replace the external WireGuard binary/MSI with wireguard-go embedded as a Go library. The helper now manages the WireGuard tunnel directly via wgctrl and the wireguard-go userspace implementation. Key changes: - Helper creates and manages the WireGuard interface directly using wireguard-go's TUN device and UAPI configuration - New internal/wgconfig package for WireGuard configuration generation - Migrate key handling to wgtypes.Key, removing custom crypto wrappers - Remove external WireGuard MSI bundles, ship wintun.dll instead - Add wintun update/verify tasks for maintaining the bundled DLLs - Simplify platform-specific helper code and remove dead functions - Add build constraints for Linux-only server binaries (gateway-agent, apiserver, prometheus-agent) instead of stub files - Update postinstall scripts and package configs for the new approach
Add iputil package with NormalizeCIDR for consistent CIDR formatting. Add publickey validation in the enroll package to reject malformed WireGuard keys at enrollment time. Update apiserver and controlplane-cli callers to use the new validation.
Add a smoke-test binary that installs the built artifact, verifies the helper service starts, checks that WireGuard routes are configured correctly, and tears down. Includes mise tasks to run the tests on macOS, Linux, and Windows.
Add smoke-test, signing, and notarization jobs to naisdevice workflow. Add AGENTS.md for AI agent instructions.
5384124 to
e3c598b
Compare
Remove manual git tag step that fails when the pre-release tag already exists from a previous run on the same PR. The softprops/action-gh-release action creates the tag itself via tag_name and target_commitish inputs, and updates the existing release if the tag already exists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces all external WireGuard binary dependencies (
wireguard-go,wg,wireguard.exe) with in-process wireguard-go and wgctrl on client platforms. Thenaisdevice-helpernow manages WireGuard interfaces, configuration, and routes entirely as a Go library — no subprocesses needed.Changes by platform
macOS
SetupInterface:tun.CreateTUN+device.NewDevice(userspace wireguard-go) + UAPI socketSyncConf: wgctrl via new sharedwgconfig.ApplyConfig()SetupRoutes: BSD routing sockets (x/net/route) instead ofroutecommandTeardownInterface: closes UAPI + wgDevice in-processLinux
SetupInterface:netlink.LinkAdd(&netlink.Wireguard{})+netlink.AddrAdd+netlink.LinkSetUpSyncConf: wgctrl viawgconfig.ApplyConfig()SetupRoutes:netlink.RouteAddinstead ofip routeTeardownInterface:netlink.LinkDelWindows
SetupInterface:tun.CreateTUN(wintun) +device.NewDevice(userspace wireguard-go) + UAPI named pipeSyncConf: wgctrl viawgconfig.ApplyConfig()SetupRoutes:winipcfg.LUID.AddIPAddress+LUID.AddRouteinstead of wireguard.exe AllowedIPs routingwintun.dllalongside binary instead of bundling WireGuard MSIShared / cleanup
internal/wgconfigpackage — shared wgctrl-based config builder and applier (with tests)internal/wireguard/keys.goMarshal,MarshalHeader,writeConfigFile,WireGuardConfigPath)wireguard-go/wireguard-toolsfrom Homebrew caskdepends_onwireguard-tools/iproute2from Nix client service PATHwintun.dllinsteadConfigure()where wrong error variable was loggedTesting
mise run check— all passing (govet, golangci-lint, staticcheck, govulncheck, ratchet)mise run test— all passing