{ config, pkgs, lib, ... }: # Collectivized from https://gist.github.com/c0deaddict/53aedbb69c8cbfebfec8f4428dc03102 ☭ let veth = "ve-transmission"; hostIp = "10.0.0.1/24"; guestIp = "10.0.0.2/24"; in { # https://mth.st/blog/nixos-wireguard-netns/ systemd.services."netns@" = { description = "%I network namespace"; before = [ "network.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; PrivateNetwork = true; ExecStart = "${pkgs.writers.writeDash "netns-up" '' ${pkgs.iproute}/bin/ip netns add $1 ${pkgs.utillinux}/bin/umount /var/run/netns/$1 ${pkgs.utillinux}/bin/mount --bind /proc/self/ns/net /var/run/netns/$1 ''} %I"; ExecStop = "${pkgs.iproute}/bin/ip netns del %I"; }; }; systemd.services."wireguard-ccvpn-fr" = { bindsTo = [ "netns@transmission.service" ]; after = [ "netns@transmission.service" ]; }; networking.wireguard.interfaces.ccvpn-fr = { ips = [ "10.128.4.199/32" "fd64:e20:68a3::4c7/128" ]; privateKeyFile = "/var/lib/secrets/ccvpn-fr-key"; socketNamespace = "init"; interfaceNamespace = "transmission"; peers = [ { publicKey = "QFbr19X11tqUZRerZgItb25FnBsNsd7NyJvAkWTRU1U="; # Forward all traffic via VPN. allowedIPs = [ "0.0.0.0/0" "::/0" ]; endpoint = "fr.204vpn.net:51820"; persistentKeepalive = 15; } ]; }; # https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking#veth systemd.services.${veth} = let ns = "transmission"; ipHost = "${pkgs.iproute}/bin/ip"; ipGuest = "${ipHost} netns exec ${ns} ${pkgs.iproute}/bin/ip"; in { description = "Veth interface for download"; bindsTo = [ "netns@${ns}.service" ]; after = [ "netns@${ns}.service" ]; wantedBy = [ "network.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = pkgs.writers.writeDash "veth-up" '' ${ipHost} link add ${veth} type veth peer name veth1 netns ${ns} ${ipHost} addr add ${hostIp} dev ${veth} ${ipHost} link set dev ${veth} up ${ipGuest} addr add ${guestIp} dev veth1 ${ipGuest} link set dev veth1 up ''; ExecStop = pkgs.writers.writeDash "veth-down" '' ${ipHost} link del ${veth} ''; }; }; networking.firewall.allowedTCPPorts = [ 9091 ]; services.nginx.enable = true; # TODO: change when headscale updates services.nginx.virtualHosts."watchtower.agatha.thorns.home.arpa" = { locations."/transmission" = { proxyPass = "http://10.0.0.2:9091/transmission"; proxyWebsockets = true; }; }; }