Add a tagged-release CI workflow and Linux/Windows packaging
Release / tsunagi-linux-aarch64 (push) Failing after 3m12s
Release / tsunagi-linux-x86_64 (push) Failing after 2m21s
Release / tsunagi-macos-aarch64 (push) Canceled after 0s
Release / tsunagi-windows-x86_64 (push) Canceled after 0s
Release / Publish release (push) Canceled after 0s
Release / tsunagi-linux-aarch64 (push) Failing after 3m12s
Release / tsunagi-linux-x86_64 (push) Failing after 2m21s
Release / tsunagi-macos-aarch64 (push) Canceled after 0s
Release / tsunagi-windows-x86_64 (push) Canceled after 0s
Release / Publish release (push) Canceled after 0s
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>
This commit is contained in:
1 parent
da7ce1dca1
commit
d1ab993dd2
5 files changed
+339
No files matched your search
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
# 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
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```sh
|
||||
sudo tsunagi status
|
||||
sudo tsunagi join <network-name> <tsn1…secret>
|
||||
```
|
||||
|
||||
## As your own user — one capability, no root at runtime
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
```sh
|
||||
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.255` route 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.
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env sh
|
||||
# Installs the tsunagi binary and, where systemd is present, a root service.
|
||||
# Run it as root (it writes under /usr/local and /etc):
|
||||
#
|
||||
# sudo ./install.sh
|
||||
#
|
||||
# PREFIX overrides the install prefix (default /usr/local).
|
||||
set -eu
|
||||
|
||||
PREFIX="${PREFIX:-/usr/local}"
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This installer writes to ${PREFIX}/bin and /etc; re-run it as root (sudo)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing tsunagi to ${PREFIX}/bin"
|
||||
install -d "${PREFIX}/bin"
|
||||
install -m 0755 "${here}/tsunagi" "${PREFIX}/bin/tsunagi"
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
echo "Installing the systemd service (runs the agent as root)"
|
||||
install -m 0644 "${here}/tsunagi.service" /etc/systemd/system/tsunagi.service
|
||||
systemctl daemon-reload
|
||||
cat <<EOF
|
||||
|
||||
Done. Start the agent with:
|
||||
|
||||
sudo systemctl enable --now tsunagi
|
||||
|
||||
Control it as root, so the client shares the agent's state directory:
|
||||
|
||||
sudo tsunagi status
|
||||
sudo tsunagi join <network-name> <tsn1…secret>
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Installed the binary; no systemd found, so no service was set up. Either:
|
||||
|
||||
* run it directly as root:
|
||||
|
||||
sudo tsunagi up
|
||||
|
||||
* or grant the capability and run it as your own user (no root at runtime):
|
||||
|
||||
sudo setcap cap_net_admin,cap_net_bind_service+p ${PREFIX}/bin/tsunagi
|
||||
tsunagi up
|
||||
|
||||
For the local DNS resolver as a non-root user, run \`tsunagi dns\` once; it
|
||||
prints the polkit rule that lets your user configure systemd-resolved.
|
||||
|
||||
* or skip the interface entirely with \`tsunagi up --no-tun\`: tunnels still
|
||||
form, they just do not reach the operating system.
|
||||
EOF
|
||||
fi
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
[Unit]
|
||||
Description=tsunagi mesh agent
|
||||
Documentation=https://github.com/Ultradesu/tsunagi
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/tsunagi up
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# This unit runs the agent as root, which covers everything it needs: creating
|
||||
# the TUN interface (CAP_NET_ADMIN), binding low ports, and configuring
|
||||
# systemd-resolved — root is not subject to polkit, so no polkit rule is needed.
|
||||
#
|
||||
# To run as a non-root user instead, uncomment the three lines below, set a
|
||||
# User=, and install the polkit rule that `tsunagi dns` prints (resolved decides
|
||||
# by user id, not capability, so the rule is what lets a non-root agent set the
|
||||
# resolver):
|
||||
#User=tsunagi
|
||||
#AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
#CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user