From 9a5427e3a0c0ccf2a82dc503149a26b23fbd6004 Mon Sep 17 00:00:00 2001 From: Azat Bahawi Date: Sun, 31 Mar 2024 21:29:27 +0300 Subject: 2024-03-31 --- modules/nixos/rtorrent.nix | 427 ++++++++++++++++++++++++--------------------- 1 file changed, 230 insertions(+), 197 deletions(-) (limited to 'modules/nixos/rtorrent.nix') diff --git a/modules/nixos/rtorrent.nix b/modules/nixos/rtorrent.nix index c39f306..82ef1b2 100644 --- a/modules/nixos/rtorrent.nix +++ b/modules/nixos/rtorrent.nix @@ -5,14 +5,18 @@ pkgs, ... }: -with lib; let +with lib; +let cfg = config.nixfiles.modules.rtorrent; -in { +in +{ options.nixfiles.modules.rtorrent = { enable = mkEnableOption "rTorrent"; flood = { - enable = mkEnableOption "Flood" // {default = cfg.enable;}; + enable = mkEnableOption "Flood" // { + default = cfg.enable; + }; domain = mkOption { description = "Domain name sans protocol scheme."; @@ -22,202 +26,223 @@ in { }; }; - config = let - user = "rtorrent"; - group = "rtorrent"; - baseDir = "/var/lib/rtorrent"; - rpcSocket = "${baseDir}/rpc.socket"; - in + config = + let + user = "rtorrent"; + group = "rtorrent"; + baseDir = "/var/lib/rtorrent"; + rpcSocket = "${baseDir}/rpc.socket"; + in mkIf cfg.enable (mkMerge [ - (let - port = 50000; - in { - ark.directories = [baseDir]; - - systemd = { - services.rtorrent = { - description = "rTorrent"; - after = ["network.target" "local-fs.target"]; - serviceConfig = let - leechDir = "${baseDir}/leech"; - seedDir = "${baseDir}/seed"; - sessionDir = "${baseDir}/session"; - logDir = "${baseDir}/log"; - configFile = let - moveCompleted = getExe (pkgs.writeShellApplication { - name = "move-completed"; - runtimeInputs = with pkgs; [ - coreutils-full - gnused - findutils + ( + let + port = 50000; + in + { + ark.directories = [ baseDir ]; + + systemd = { + services.rtorrent = { + description = "rTorrent"; + after = [ + "network.target" + "local-fs.target" + ]; + serviceConfig = + let + leechDir = "${baseDir}/leech"; + seedDir = "${baseDir}/seed"; + sessionDir = "${baseDir}/session"; + logDir = "${baseDir}/log"; + configFile = + let + moveCompleted = getExe ( + pkgs.writeShellApplication { + name = "move-completed"; + runtimeInputs = with pkgs; [ + coreutils-full + gnused + findutils + ]; + text = '' + set -x + + leech_path="$1" + seed_path="$2" + # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')" + + mkdir -pv "$seed_path" + mv -fv "$leech_path" "$seed_path" + ''; + } + ); + in + pkgs.writeText "rtorrent.rc" '' + method.insert = cfg.leech, private|const|string, (cat, "${leechDir}") + method.insert = cfg.seed, private|const|string, (cat, "${seedDir}") + method.insert = cfg.session, private|const|string, (cat, "${sessionDir}") + method.insert = cfg.log, private|const|string, (cat, "${logDir}") + method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}") + + directory.default.set = (cat, (cfg.leech)) + session.path.set = (cat, (cfg.session)) + + network.port_range.set = ${toString port}-${toString port} + network.port_random.set = no + + dht.mode.set = disable + protocol.pex.set = no + + trackers.use_udp.set = no + + protocol.encryption.set = allow_incoming,try_outgoing,enable_retry + + pieces.memory.max.set = ${toString (pow 2 11)}M + pieces.preload.type.set = 2 + + network.xmlrpc.size_limit.set = ${toString (pow 2 17)} + + network.max_open_files.set = ${toString (pow 2 10)} + network.max_open_sockets.set = ${toString (pow 2 10)} + + network.http.max_open.set = ${toString (pow 2 8)} + + throttle.global_down.max_rate.set_kb = 0 + throttle.global_up.max_rate.set_kb = 0 + + encoding.add = UTF-8 + system.umask.set = 0027 + system.cwd.set = (directory.default) + + network.scgi.open_local = (cat, (cfg.rpcsocket)) + + method.insert = d.move_completed, simple, "\ + d.directory.set=$argument.1=;\ + execute=${moveCompleted}, $argument.0=, $argument.1=;\ + d.save_full_session=\ + " + method.insert = d.leech_path, simple, "\ + if=(d.is_multi_file),\ + (cat, (d.directory), /),\ + (cat, (d.directory), /, (d.name))\ + " + method.insert = d.seed_path, simple, "\ + cat=$cfg.seed=, /, $d.custom1=\ + " + method.set_key = event.download.finished, move_complete, "\ + d.move_completed=$d.leech_path=, $d.seed_path=\ + " + + log.open_file = "log", (cat, (cfg.log), "/", "default.log") + log.add_output = "info", "log" + log.execute = (cat, (cfg.log), "/", "execute.log") + ''; + in + { + Restart = "on-failure"; + RestartSec = 3; + + KillMode = "process"; + KillSignal = "SIGHUP"; + + User = user; + Group = group; + + ExecStartPre = concatStringsSep " " [ + "${pkgs.coreutils-full}/bin/mkdir -p" + leechDir + seedDir + sessionDir + logDir + ]; + ExecStart = concatStringsSep " " [ + (getExe pkgs.rtorrent) + "-n" + "-o system.daemon.set=true" + "-o network.bind_address.set=0.0.0.0" + "-o import=${configFile}" + ]; + ExecStop = concatStringsSep " " [ + "${pkgs.coreutils-full}/bin/rm -rf" + rpcSocket ]; - text = '' - set -x - - leech_path="$1" - seed_path="$2" - # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')" - - mkdir -pv "$seed_path" - mv -fv "$leech_path" "$seed_path" - ''; - }); - in - pkgs.writeText "rtorrent.rc" '' - method.insert = cfg.leech, private|const|string, (cat, "${leechDir}") - method.insert = cfg.seed, private|const|string, (cat, "${seedDir}") - method.insert = cfg.session, private|const|string, (cat, "${sessionDir}") - method.insert = cfg.log, private|const|string, (cat, "${logDir}") - method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}") - - directory.default.set = (cat, (cfg.leech)) - session.path.set = (cat, (cfg.session)) - - network.port_range.set = ${toString port}-${toString port} - network.port_random.set = no - - dht.mode.set = disable - protocol.pex.set = no - - trackers.use_udp.set = no - - protocol.encryption.set = allow_incoming,try_outgoing,enable_retry - - pieces.memory.max.set = ${toString (pow 2 11)}M - pieces.preload.type.set = 2 - - network.xmlrpc.size_limit.set = ${toString (pow 2 17)} - - network.max_open_files.set = ${toString (pow 2 10)} - network.max_open_sockets.set = ${toString (pow 2 10)} - - network.http.max_open.set = ${toString (pow 2 8)} - - throttle.global_down.max_rate.set_kb = 0 - throttle.global_up.max_rate.set_kb = 0 - - encoding.add = UTF-8 - system.umask.set = 0027 - system.cwd.set = (directory.default) - - network.scgi.open_local = (cat, (cfg.rpcsocket)) - - method.insert = d.move_completed, simple, "\ - d.directory.set=$argument.1=;\ - execute=${moveCompleted}, $argument.0=, $argument.1=;\ - d.save_full_session=\ - " - method.insert = d.leech_path, simple, "\ - if=(d.is_multi_file),\ - (cat, (d.directory), /),\ - (cat, (d.directory), /, (d.name))\ - " - method.insert = d.seed_path, simple, "\ - cat=$cfg.seed=, /, $d.custom1=\ - " - method.set_key = event.download.finished, move_complete, "\ - d.move_completed=$d.leech_path=, $d.seed_path=\ - " - - log.open_file = "log", (cat, (cfg.log), "/", "default.log") - log.add_output = "info", "log" - log.execute = (cat, (cfg.log), "/", "execute.log") - ''; - in { - Restart = "on-failure"; - RestartSec = 3; - - KillMode = "process"; - KillSignal = "SIGHUP"; - User = user; - Group = group; + RuntimeDirectory = "rtorrent"; + RuntimeDirectoryMode = 750; + UMask = 27; + AmbientCapabilities = [ "" ]; + CapabilityBoundingSet = [ "" ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProcSubset = "pid"; + RemoveIPC = true; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@resources" + "~@privileged" + ]; + }; + wantedBy = [ "multi-user.target" ]; + }; - ExecStartPre = concatStringsSep " " [ - "${pkgs.coreutils-full}/bin/mkdir -p" - leechDir - seedDir - sessionDir - logDir - ]; - ExecStart = concatStringsSep " " [ - (getExe pkgs.rtorrent) - "-n" - "-o system.daemon.set=true" - "-o network.bind_address.set=0.0.0.0" - "-o import=${configFile}" - ]; - ExecStop = concatStringsSep " " [ - "${pkgs.coreutils-full}/bin/rm -rf" - rpcSocket - ]; + tmpfiles.rules = [ "d '${baseDir}' 0750 ${user} ${group} -" ]; + }; - RuntimeDirectory = "rtorrent"; - RuntimeDirectoryMode = 0750; - UMask = 0027; - AmbientCapabilities = [""]; - CapabilityBoundingSet = [""]; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = true; - PrivateTmp = true; - PrivateUsers = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProcSubset = "pid"; - RemoveIPC = true; - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - SystemCallFilter = ["@system-service" "~@resources" "~@privileged"]; + users = { + users.${user} = { + inherit group; + shell = pkgs.bashInteractive; + home = baseDir; + description = "rTorrent"; + isSystemUser = true; }; - wantedBy = ["multi-user.target"]; + groups.${group} = { }; }; - - tmpfiles.rules = ["d '${baseDir}' 0750 ${user} ${group} -"]; - }; - - users = { - users.${user} = { - inherit group; - shell = pkgs.bashInteractive; - home = baseDir; - description = "rTorrent"; - isSystemUser = true; + my.extraGroups = [ group ]; + + networking.firewall.allowedTCPPorts = [ port ]; + + boot.kernel.sysctl = { + "net.core.rmem_max" = mkOverride 500 (pow 2 24); + "net.core.wmem_max" = mkOverride 500 (pow 2 24); + "net.ipv4.tcp_fin_timeout" = mkOverride 500 30; + "net.ipv4.tcp_rmem" = mkOverride 500 (mkTcpMem 12 23 24); + "net.ipv4.tcp_slow_start_after_idle" = 0; + "net.ipv4.tcp_tw_recycle" = mkOverride 500 1; + "net.ipv4.tcp_tw_reuse" = mkOverride 500 1; + "net.ipv4.tcp_wmem" = mkOverride 500 (mkTcpMem 12 23 24); }; - groups.${group} = {}; - }; - my.extraGroups = [group]; - - networking.firewall.allowedTCPPorts = [port]; - - boot.kernel.sysctl = { - "net.core.rmem_max" = mkOverride 500 (pow 2 24); - "net.core.wmem_max" = mkOverride 500 (pow 2 24); - "net.ipv4.tcp_fin_timeout" = mkOverride 500 30; - "net.ipv4.tcp_rmem" = mkOverride 500 (mkTcpMem 12 23 24); - "net.ipv4.tcp_slow_start_after_idle" = 0; - "net.ipv4.tcp_tw_recycle" = mkOverride 500 1; - "net.ipv4.tcp_tw_reuse" = mkOverride 500 1; - "net.ipv4.tcp_wmem" = mkOverride 500 (mkTcpMem 12 23 24); - }; - }) - (let - port = 50001; - pkg = pkgs.nodePackages.flood; - in + } + ) + ( + let + port = 50001; + pkg = pkgs.nodePackages.flood; + in mkIf cfg.flood.enable { nixfiles.modules.nginx = { enable = true; - upstreams.flood.servers."127.0.0.1:${toString port}" = {}; + upstreams.flood.servers."127.0.0.1:${toString port}" = { }; virtualHosts.${cfg.flood.domain} = { root = "${pkg}/lib/node_modules/flood/dist/assets"; locations = { @@ -233,8 +258,11 @@ in { systemd.services.flood = { description = "Flood"; - after = ["network.target" "rtorrent.service"]; - path = with pkgs; [mediainfo]; + after = [ + "network.target" + "rtorrent.service" + ]; + path = with pkgs; [ mediainfo ]; serviceConfig = { Restart = "on-failure"; RestartSec = 3; @@ -255,10 +283,10 @@ in { ]; RuntimeDirectory = "rtorrent"; - RuntimeDirectoryMode = 0750; - UMask = 0027; - AmbientCapabilities = [""]; - CapabilityBoundingSet = [""]; + RuntimeDirectoryMode = 750; + UMask = 27; + AmbientCapabilities = [ "" ]; + CapabilityBoundingSet = [ "" ]; LockPersonality = true; NoNewPrivileges = true; PrivateDevices = true; @@ -274,7 +302,11 @@ in { ProcSubset = "pid"; ProtectProc = "invisible"; RemoveIPC = true; - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; @@ -288,8 +320,9 @@ in { "~@resources" ]; }; - wantedBy = ["multi-user.target"]; + wantedBy = [ "multi-user.target" ]; }; - }) + } + ) ]); } -- cgit v1.2.3