nixos-config/machines/fuuko/services/torrent.nix

200 lines
5.0 KiB
Nix

{ config, inputs, lib, pkgs, ... }:
let
homeDir = "/var/lib/aria2";
downloadDir = "/data/torrent";
sessionFile = "${homeDir}/session";
settings = {
# locations
dir = downloadDir;
# logging
show-console-readout = false;
summary-interval = 0;
# rpc
enable-rpc = true;
# permanent queue
bt-load-saved-metadata = true;
bt-save-metadata = true;
force-save = true;
input-file = sessionFile;
save-session = sessionFile;
save-session-interval = 900; # automatic saving
# network
async-dns-server = "193.138.218.74"; # aria2 does not respect netns resolv.conf
dht-listen-port = 56595;
listen-port = 56718;
interface = "wg-aria";
# limits
max-concurrent-downloads = 65536;
max-overall-download-limit = "6M";
max-overall-upload-limit = "4M";
seed-ratio = 0; # do not stop seeding after reaching ratio
};
toString' = value:
if lib.isBool value
then (if value then "true" else "false")
else (toString value);
configFile = pkgs.writeText "aria2.conf" (lib.concatStringsSep
"\n"
(lib.mapAttrsToList
(k: v: "${k}=${toString' v}")
settings));
mkProxyService = socket: port: {
wantedBy = [ "multi-user.target" ];
after = [ "wireguard-wg-aria.service" ];
partOf = [ "wireguard-wg-aria.service" ];
serviceConfig = {
PrivateNetwork = true;
NetworkNamespacePath = "/run/netns/aria2";
Restart = "always";
ExecStart = "${pkgs.socat}/bin/socat UNIX-LISTEN:${socket},fork,reuseaddr,mode=660,unlink-early TCP:127.0.0.1:${toString port}";
User = "aria2";
Group = "nginx";
# systemd-analyze --no-pager security aria2-rpc-proxy.service
CapabilityBoundingSet = null;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectHome = true;
RestrictNamespaces = true;
SystemCallFilter = "@system-service";
};
};
in
{
users.users.aria2 = {
group = "aria2";
uid = config.ids.uids.aria2;
home = homeDir;
};
users.groups.aria2.gid = config.ids.gids.aria2;
systemd.tmpfiles.rules = [
"d '${downloadDir}' 0775 aria2 users - -"
"d '${homeDir}' 0771 aria2 aria2 - -"
];
sops.secrets.wg-aria-private-key.sopsFile = ../secrets.yaml;
networking.wireguard.interfaces.wg-aria = {
interfaceNamespace = "aria2";
preSetup = "ip netns add aria2 && ip -n aria2 link set lo up";
postShutdown = "ip netns del aria2";
privateKeyFile = config.sops.secrets.wg-aria-private-key.path;
} // (import ../secrets/aria2-wireguard.nix); # potentially sensitive data
environment.etc."netns/aria2/resolv.conf".text = ''
nameserver 193.138.218.74
'';
systemd.services.aria2 = {
description = "aria2 Service";
after = [ "wireguard-wg-aria.service" ];
requires = [ "wireguard-wg-aria.service" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
if [[ ! -e "${sessionFile}" ]]; then
touch "${sessionFile}"
fi
'';
serviceConfig = {
PrivateNetwork = true;
NetworkNamespacePath = "/run/netns/aria2";
Restart = "always";
ExecStart = "${pkgs.aria2}/bin/aria2c --conf-path=${configFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
User = "aria2";
Group = "aria2";
# Increase number of open file descriptors (default: 1024)
LimitNOFILE = 65536;
# systemd-analyze --no-pager security aria2.service
CapabilityBoundingSet = null;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectHome = true;
RestrictNamespaces = true;
SystemCallFilter = "@system-service";
};
};
systemd.services.aria2-rpc-proxy = mkProxyService "${homeDir}/rpc.sock" 6800;
services.aria2_exporter = {
enable = true;
listenAddress = "localhost:9578";
};
systemd.services.aria2_exporter = {
after = [ "wireguard-wg-aria.service" ];
partOf = [ "wireguard-wg-aria.service" ];
serviceConfig = {
PrivateNetwork = true;
NetworkNamespacePath = "/run/netns/aria2";
};
};
systemd.services.aria2_exporter-proxy = mkProxyService "${homeDir}/metrics.sock" 9578;
services.nginx.virtualHosts."torrent.sbruder.de" = {
enableACME = true;
forceSSL = true;
# treated as state
basicAuthFile = "${homeDir}/htpasswd";
locations = {
"/" = {
root = inputs.AriaNg.packages.${config.nixpkgs.system}.AriaNg;
};
"/jsonrpc" = {
proxyPass = "http://unix:${homeDir}/rpc.sock";
proxyWebsockets = true;
};
"/download/" = {
alias = "${downloadDir}/";
extraConfig = ''
autoindex on;
'';
};
"=/metrics" = {
proxyPass = "http://unix:${homeDir}/metrics.sock";
};
};
};
services.nginx.virtualHosts."aria2-metrics" = {
listen = lib.singleton {
addr = "127.0.0.1";
port = 9578;
};
locations."=/metrics" = {
proxyPass = "http://unix:${homeDir}/metrics.sock";
};
};
environment.systemPackages = with pkgs; [
aria2
mktorrent
];
}