diff --git a/home-modules/default.nix b/home-modules/default.nix index 1d3394b..03d1423 100644 --- a/home-modules/default.nix +++ b/home-modules/default.nix @@ -10,6 +10,7 @@ ./terminal.nix ./browser.nix ./desktop.nix + ./qbittorrent.nix ./opencode.nix ]; } diff --git a/home-modules/packages.nix b/home-modules/packages.nix index fd0d744..0f24bd2 100644 --- a/home-modules/packages.nix +++ b/home-modules/packages.nix @@ -174,7 +174,6 @@ in pavucontrol prismlauncher qpwgraph - qbittorrent-enhanced signal-desktop slack vesktop diff --git a/home-modules/qbittorrent.nix b/home-modules/qbittorrent.nix new file mode 100644 index 0000000..3cc5c0f --- /dev/null +++ b/home-modules/qbittorrent.nix @@ -0,0 +1,66 @@ +{ config, pkgs, ... }: + +let + configureQbittorrentTailscale = pkgs.writeShellApplication { + name = "configure-qbittorrent-tailscale"; + runtimeInputs = [ + pkgs.coreutils + pkgs.crudini + ]; + text = '' + conf="''${XDG_CONFIG_HOME:-$HOME/.config}/qBittorrent/qBittorrent.conf" + mkdir -p "$(dirname "$conf")" + + crudini --set "$conf" BitTorrent 'Session\Interface' tailscale0 + crudini --set "$conf" BitTorrent 'Session\InterfaceName' tailscale0 + crudini --set "$conf" BitTorrent 'Session\LSDEnabled' false + crudini --del "$conf" BitTorrent 'Session\InterfaceAddress' 2>/dev/null || true + ''; + }; + + qbittorrentTailscale = pkgs.symlinkJoin { + name = "qbittorrent-enhanced-tailscale"; + paths = [ pkgs.qbittorrent-enhanced ]; + postBuild = '' + rm -f "$out/bin/qbittorrent" + # Enforce qBittorrent's bind settings, then add a systemd interface allowlist. + cat > "$out/bin/qbittorrent" <<'EOF' + #!${pkgs.runtimeShell} + set -eu + + ${configureQbittorrentTailscale}/bin/configure-qbittorrent-tailscale + + if [ -z "''${XDG_RUNTIME_DIR:-}" ]; then + printf '%s\n' 'qBittorrent not started: XDG_RUNTIME_DIR is not set, so systemd cannot apply the Tailscale-only network restriction.' >&2 + exit 1 + fi + + exec ${pkgs.systemd}/bin/systemd-run \ + --user \ + --scope \ + --quiet \ + --collect \ + --property='RestrictNetworkInterfaces=lo tailscale0' \ + -- \ + ${pkgs.qbittorrent-enhanced}/bin/qbittorrent "$@" + EOF + chmod +x "$out/bin/qbittorrent" + + desktop="$out/share/applications/org.qbittorrent.qBittorrent.desktop" + if [ -e "$desktop" ]; then + rm -f "$desktop" + install -Dm644 ${pkgs.qbittorrent-enhanced}/share/applications/org.qbittorrent.qBittorrent.desktop "$desktop" + substituteInPlace "$desktop" \ + --replace-fail 'Exec=qbittorrent %U' "Exec=$out/bin/qbittorrent %U" + fi + ''; + }; +in + +{ + home.activation.configureQbittorrentTailscale = config.lib.dag.entryAfter [ "writeBoundary" ] '' + ${configureQbittorrentTailscale}/bin/configure-qbittorrent-tailscale + ''; + + home.packages = [ qbittorrentTailscale ]; +}