62db1e2a9e1c7f5cd05a452d2062dd73daed2549
`--wireguard-config` is now the only thing an operator supplies. torad re-executes itself inside a private user+network namespace, brings up a userspace WireGuard datapath, and binds every torrent socket to it. No root, no wg-quick, no pre-created interface, no kernel module, no one-time host setup. The mechanism differs from what was planned, because the plan's assumptions did not survive being checked against the actual binaries: - pasta already creates an unprivileged user+net namespace with full capabilities and a configured tap interface, so the hand-rolled unshare(CLONE_NEWUSER|CLONE_NEWNET) with uid_map, gid_map and setgroups=deny is gone. torad re-execs itself under pasta instead. - WG_SOCKET_DIRECTORY does not exist; wireguard-go's socket directory is a build-time linker variable. WG_UAPI_FD does not avoid it either, because UAPIListen inotify-watches that path even when handed a pre-bound socket. Since /var/run is a symlink to /run, a tmpfs over /var inside a private mount namespace makes /var/run/wireguard writable while leaving the real /run visible -- which matters, because torad's gRPC socket lives under /run/user and the aggregator connects to it from the host. - The peer endpoint needs a host route via pasta's gateway before the default route moves to wg0, or WireGuard's own handshake is routed into the tunnel it is trying to establish. The device is configured by speaking WireGuard's UAPI protocol over its unix socket, so wireguard-tools is not a dependency either. If the datapath exits, torad shuts down instead of routing around it: a live torad with a dead tunnel is the failure mode that leaks. pasta also creates a PID namespace, so the pid file is written on the host before the re-exec and not again inside -- otherwise it would record PID 1, which names init when read from the host. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
Languages
Rust
99.1%
Nix
0.9%