nixos-config/machines/fuuko/services/torrent.nix
Simon Bruder 10ced7f2bb
fuuko/torrent: Make socat work after forced stop
This should improve behavour after e.g. a power outage.
2021-05-03 10:17:00 +02:00

209 lines
5.4 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,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 = "${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 = pkgs.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
];
}