Pushing a `v*` tag now builds the agent for every supported target and attaches the archives to a GitHub release. Modelled on the furumi release workflow (a build matrix, then a publish job that runs `gh release create`), adapted to this project's two differences: it needs system integration (capabilities/polkit on Linux, elevation+wintun on Windows, a root daemon on macOS), and its users run varied distros, not just Ubuntu. Linux is built as a fully **static musl** binary with cargo-zigbuild, so one artifact runs on Arch, Alpine, NixOS and old-glibc systems alike, and can be repackaged into whatever a distro prefers later. musl has no prebuilt aws-lc-sys bindings, so the Linux jobs install cmake + libclang (bindgen) and zig (the cross C compiler zigbuild drives). macOS (aarch64) and Windows (x86_64) build natively; Linux covers x86_64 and aarch64. Targets: x86_64/aarch64 linux-musl, aarch64 macOS, x86_64 Windows. Each archive carries the binary, the top-level README, and the platform's install notes plus integration files: - dist/linux/: a static-friendly README, a systemd unit (runs as root, so no capability grant or polkit rule is needed; a commented non-root variant is included), and an install.sh that drops the binary and the unit or prints the setcap/polkit alternative. - dist/windows/: install notes covering wintun.dll and Run-as-administrator. - dist/macos/: the existing LaunchDaemon plist and notes, now also shipped in the archive. Not exercised yet: the workflow only runs on a real tag push, and the aws-lc-sys-under-musl build has not been run locally in this session (no zig toolchain here). YAML and install.sh syntax are validated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.1 KiB
Running tsunagi on Linux
This archive holds a static tsunagi binary (musl), so it runs on any
distribution — Arch, Alpine, NixOS, old glibc systems — with no shared-library
dependencies. Alongside it are a systemd unit and an installer.
Creating the TUN interface needs CAP_NET_ADMIN, and configuring
systemd-resolved is decided by polkit (by user id, not capability). There are
three ways to satisfy that; pick one.
Quick install — systemd service as root
sudo ./install.sh
sudo systemctl enable --now tsunagi
The service runs the agent as root, so the interface, low ports and the resolver all just work (root is not subject to polkit). Control it as root, so the client resolves the same state directory the daemon uses:
sudo tsunagi status
sudo tsunagi join <network-name> <tsn1…secret>
As your own user — one capability, no root at runtime
sudo install -m 0755 tsunagi /usr/local/bin/tsunagi
sudo setcap cap_net_admin,cap_net_bind_service+p /usr/local/bin/tsunagi
tsunagi up
Nothing is left behind and nothing runs as root. The capability is lost on every
rebuild or copy of the binary, so re-run setcap after replacing it. For the
local DNS resolver, run tsunagi dns once: it prints the exact polkit rule that
lets your user configure systemd-resolved, ready to paste.
Without touching the OS
tsunagi up --no-tun
Tunnels form and handshake between agents, but no interface, address or route is created, so traffic never reaches the operating system. Needs no privileges.
What the agent installs
Everything is tagged to its own interface, computed from local state, and reversible — removed when a network leaves, broadcast is turned off, or the agent stops:
- a TUN interface configured over netlink (addresses, MTU, up);
- while broadcast is on, a
255.255.255.255route through the interface and an inbound-UDP firewall allowance from the overlay range (iptables, tagged); - the systemd-resolved setting that sends the overlay zones' questions to the local resolver.
Nothing taken from a remote peer ever becomes a path, a command argument or an OS setting.