# transmission-bt BitTorrent client in an unprivileged Incus container on `nuc`, with an **always-on VPN**: all peer traffic exits via ks4's public IP through a WireGuard tunnel to the `wireguard` container on ks4. Kill switch by construction — `eth0` has **no default route**, so with the tunnel down the container simply has no path to the internet. - Image: `images:ubuntu/24.04`, IP: `192.168.0.7` (macvlan, static via netplan) - Web UI: `http://192.168.0.7:9091` — no auth (`rpc-authentication-required: false`); access control is the RPC whitelist (`192.168.0.*` only) - Egress: WG peer `10.8.0.21` → `193.70.35.17:51845`, `AllowedIPs 0.0.0.0/0` (verified: `curl ifconfig.me` from the container returns ks4's IP) - Downloads: `/media/downloads` (= `usb4t/media`, same dataset Jellyfin reads); in-progress files in `/media/.incomplete` so Jellyfin never scans partials - `transmission-daemon` is `BindsTo=wg-quick@wg0.service` and binds peer traffic to `10.8.0.21` — three independent layers against leaks (no default route, unit binding, socket binding) ## Anti-leak design 1. netplan gives `eth0` only: LAN `/24` (web UI + DNS via blocky) and a `/32` host route to the WG endpoint via the home gateway. 2. `wg-quick` full-tunnel mode adds its fwmark policy routing + iptables anti-leak rule (`iptables` package required — its absence makes `wg-quick` fail with `iptables-restore: command not found`). 3. LAN traffic keeps working thanks to wg-quick's `suppress_prefixlength 0` rule (connected routes win over the tunnel's default). ## Install script Run as root on the Incus host. Requires the peer added on ks4 (below). ```bash #!/usr/bin/env bash set -euxo pipefail CNAME="${CNAME:-transmission-bt}" IMAGE="${IMAGE:-images:ubuntu/24.04}" incus launch "$IMAGE" "$CNAME" sleep 8 incus config set "$CNAME" environment.DEBIAN_FRONTEND=noninteractive incus exec "$CNAME" -- timedatectl set-timezone Europe/Paris # static LAN config, NO default route (kill switch), /32 to the WG endpoint incus exec "$CNAME" -- bash -c 'cat > /etc/netplan/10-lxc.yaml < /etc/wireguard/wg0.key wg pubkey < /etc/wireguard/wg0.key cat > /etc/wireguard/wg0.conf < /etc/systemd/system/transmission-daemon.service.d/vpn.conf < allowed-ips 10.8.0.21/32 incus exec wireguard -- wg-quick save wg0 ``` ## Verification ```sh incus exec transmission-bt -- wg show wg0 latest-handshakes # non-zero timestamp incus exec transmission-bt -- curl -s https://ifconfig.me # must print 193.70.35.17 incus exec transmission-bt -- bash -c "ping -c1 -W2 8.8.8.8 || echo kill-switch OK" # with wg0 down # web UI must be tested from a LAN machine — the macvlan quirk means the # nuc host itself cannot reach 192.168.0.7 ``` ## Notes - No inbound peer port is forwarded (would need a proxy device on ks4 + DNAT through the tunnel); torrents work fine outbound-only, just connect to fewer peers. - Jellyfin sees finished downloads under `/media/downloads` — add it as a library folder or move files into the movie/show trees. - The image server check can make `incus launch` hang on slow WAN — launching from the cached image fingerprint (`incus image list`) bypasses it.