nixos-config/machines/fuuko/services/torrent.nix
Simon Bruder 515939677b
fuuko/torrent: Add resolv.conf to aria2 netns
Even though aria2 doesn’t respect it, it is useful for for debugging.
2021-03-08 19:38:26 +01:00

214 lines
5.6 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ config, 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 = 54971;
listen-port = 54931;
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));
# Without this patch, the download and upload lengths are wrong after pausing
# and unpausing. I dont patch this globally (in the overlay), since aria2 is
# in the user environment and would have to be rebuilt on slow machines.
aria2 = pkgs.aria2.overrideAttrs (o: o // {
patches = [
(pkgs.fetchpatch {
url = "https://github.com/aria2/aria2/commit/6ebdddb9f159e87923736f25900897b3602305f9.diff";
sha256 = "1j5mnafiv92xnzghh03hfdvpn9647vfdcipamnvi8hnzk3ak4mj7";
})
];
});
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 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 - -"
];
krops.secrets.wg-aria-private-key = { };
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.krops.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 = "${aria2}/bin/aria2c --conf-path=${configFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
User = "aria2";
Group = "aria2";
# 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 = toString (import
(pkgs.fetchzip {
url = "https://git.sbruder.de/simon/AriaNg/archive/51c53f298091a6a6b6077febc2bc9370acb47271.tar.gz";
sha256 = "0f8j86l3fw71q1m00radlv2bg33l9jad0razyalvspzam3p3bsk1";
})
{ inherit pkgs; });
};
"/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
];
}