Files
tsunagi/dist/linux/README.md
T
UltradesuandClaude Opus 4.8 63178574ce
Release / tsunagi-linux-aarch64 (push) Successful in 2m39s
Release / tsunagi-linux-x86_64 (push) Successful in 2m32s
Release / tsunagi-macos-aarch64 (push) Canceled after 0s
Release / tsunagi-windows-x86_64 (push) Canceled after 0s
Release / Publish release (push) Canceled after 0s
Package as a dedicated tsunagi user; add Arch packages
Reworks the Linux packaging so the service runs as an unprivileged, dedicated
"tsunagi" user instead of root — the point of a native package is to set things
up properly for that OS's users — and adds Arch Linux packages beside the deb.
Both package families are built from the already-compiled static binary; nothing
is recompiled.

Service model (shared systemd unit, dist/linux/tsunagi.service):
- User=tsunagi with AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE, so
  it creates the TUN and binds low ports without root.
- StateDirectory/CacheDirectory/RuntimeDirectory give it /var/lib/tsunagi,
  /var/cache/tsunagi and /run/tsunagi, and the agent is pointed at them (and the
  socket at /run/tsunagi/agent.sock) through TSUNAGI_* env in the unit.
- The polkit rule now grants the resolve1 actions to the "tsunagi" group; the
  service user is in it, and admins can add themselves.

CLI: when no state dir is chosen, the control commands prefer the system
service's socket at /run/tsunagi/agent.sock when it exists, so `sudo tsunagi
status`/`join` reach the packaged daemon with no flags. A per-user agent (its
socket absent from /run) still uses its own.

Packaging:
- deb (build-deb.sh): postinst now creates the tsunagi system user+group; unit
  installed to /lib/systemd/system, binary to /usr/bin.
- Arch (new dist/arch/build-pkg.sh): a dependency-free .pkg.tar.zst assembled
  with bsdtar + zstd (no makepkg, no Arch host) — .PKGINFO, a .INSTALL scriptlet
  that creates the user and reloads systemd, and a gzipped .MTREE; unit to
  /usr/lib/systemd/system.
- The polkit rule moved to dist/linux (shared by deb, Arch and the tarball), and
  the tarball install.sh now creates the user and installs the unit + rule.
- Both release workflows build the deb and the Arch package on the two Linux
  matrix entries (deb_arch/pkg_arch), install libarchive-tools+zstd for it, and
  attach both to the release (Gitea API loop / gh).

Not exercised in this session: the .deb and .pkg.tar.zst build and install only
on Linux (no dpkg-deb/bsdtar+pacman locally); CLI build, clippy, fmt and tests
pass, and all shell/YAML is syntax-checked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 13:46:27 +01:00

68 lines
2.4 KiB
Markdown

# 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, a polkit rule, and an installer.
Creating the TUN interface needs `CAP_NET_ADMIN`, and configuring
systemd-resolved is decided by polkit. There are three ways to run it; pick one.
> On Debian/Ubuntu and Arch, prefer the native package (`.deb` / `.pkg.tar.zst`)
> from the release — it does all of the below for you.
## Quick install — systemd service as a dedicated user
```sh
sudo ./install.sh
sudo systemctl enable --now tsunagi
```
The service runs as an unprivileged `tsunagi` user with just `CAP_NET_ADMIN`
and `CAP_NET_BIND_SERVICE` (granted by systemd), not root. systemd creates its
state (`/var/lib/tsunagi`), cache (`/var/cache/tsunagi`) and runtime
(`/run/tsunagi`) directories, and the polkit rule lets it configure the
resolver. Control it with `sudo` — the CLI finds the running service's socket at
`/run/tsunagi/agent.sock` with no flags:
```sh
sudo tsunagi status
sudo tsunagi join <network-name> <tsn1…secret>
```
## As your own user — one capability, no service
```sh
sudo install -m 0755 tsunagi /usr/local/bin/tsunagi
sudo setcap cap_net_admin,cap_net_bind_service+p /usr/local/bin/tsunagi
sudo usermod -aG tsunagi "$USER" # so the resolver works; log in again after
tsunagi up
```
Nothing runs as root. The capability is lost on every rebuild or copy of the
binary, so re-run `setcap` after replacing it. The agent uses your per-user
state directory and socket, so plain `tsunagi status` (no sudo) reaches it.
## 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.