{ config, pkgs, ... }: { # Secrets sops.secrets.transmission-ovpn-config = { sopsFile = ./resources/secrets/transmission.yaml; key = "ovpn-config"; }; sops.secrets.transmission-ovpn-auth = { sopsFile = ./resources/secrets/transmission.yaml; key = "ovpn-auth"; }; # Container containers.transmission = let home = "/var/lib/transmission"; download-dir = "${home}/complete"; incomplete-dir = "${home}/incomplete"; in { autoStart = true; privateNetwork = true; enableTun = true; # OpenVPN requires hostBridge = "br-lan0"; localMacAddress = "02:00:00:00:00:07"; # Download dirs bindMounts = { "${download-dir}" = { hostPath = "/media/ingens/media/.incomplete"; isReadOnly = false; }; "${incomplete-dir}" = { hostPath = "/media/ingens/media/.complete"; isReadOnly = false; }; }; # Bind secrets bindMounts."/run/secrets/ovpn-config.ovpn" = { hostPath = config.sops.secrets.transmission-ovpn-config.path; isReadOnly = true; }; bindMounts."/run/secrets/ovpn-auth" = { hostPath = config.sops.secrets.transmission-ovpn-auth.path; isReadOnly = true; }; config = { lib, config, ... }: { # Network networking.enableIPv6 = false; # Prevent ip leaks networking.interfaces.eth0.useDHCP = true; networking.firewall.interfaces = { eth0.allowedTCPPorts = [ 80 ]; # RPC interface # Torrent ports tun0 = { allowedTCPPorts = [ 51413 ]; allowedUDPPorts = [ 51413 ]; }; }; # Transmission services.transmission = { inherit home; enable = true; settings = { inherit download-dir incomplete-dir; }; }; # TODO remove (#258793) systemd.services.transmission.serviceConfig = { RootDirectoryStartOnly = lib.mkForce null; RootDirectory = lib.mkForce null; }; # Reverse proxy services.caddy = { enable = true; virtualHosts.":80".extraConfig = '' reverse_proxy localhost:9091 ''; }; # OpenVPN services.openvpn.servers.main = { config = '' config /run/secrets/ovpn-config.ovpn auth-user-pass /run/secrets/ovpn-auth ''; autoStart = true; updateResolvConf = true; }; # VPN killswitch networking.firewall.extraCommands = '' # Get domain name host and port from ovpn config SERVER_HOST=$(${pkgs.gawk}/bin/awk '/^remote /{print $2;exit}' /run/secrets/ovpn-config.ovpn) SERVER_PORT=$(${pkgs.gawk}/bin/awk '/^remote /{print $3;exit}' /run/secrets/ovpn-config.ovpn) # Resolve server ip from host while [ -z "$SERVER_IP" ]; do sleep 3 SERVER_IP=$(${pkgs.getent}/bin/getent hosts "$SERVER_HOST" 2>/dev/null | ${pkgs.gawk}/bin/awk '{print $1}') echo "SERVER_IP: $SERVER_IP" done # Only allow out traffic from tun0 ${pkgs.iptables}/bin/iptables -P OUTPUT DROP ${pkgs.iptables}/bin/iptables -A OUTPUT -o lo -j ACCEPT ${pkgs.iptables}/bin/iptables -A OUTPUT -o tun0 -j ACCEPT ${pkgs.iptables}/bin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Exception: allow established connections ${pkgs.iptables}/bin/iptables -A OUTPUT -p udp -d "$SERVER_IP" --dport "$SERVER_PORT" -j ACCEPT # Allow DNS DNS_IP=$(${pkgs.gawk}/bin/awk '/^nameserver /{print $2; exit}' /etc/resolv.conf) ${pkgs.iptables}/bin/iptables -A OUTPUT -o eth0 -p udp -d "$DNS_IP" --dport 53 -j ACCEPT ${pkgs.iptables}/bin/iptables -A OUTPUT -o eth0 -p tcp -d "$DNS_IP" --dport 53 -j ACCEPT # Allow transmission RPC ''; system.stateVersion = "26.05"; }; }; }