fuuko: Add aria2
This commit is contained in:
parent
07f152cb20
commit
786edd1caf
|
@ -9,6 +9,7 @@
|
||||||
./services/media.nix
|
./services/media.nix
|
||||||
./services/prometheus.nix
|
./services/prometheus.nix
|
||||||
./services/scan.nix
|
./services/scan.nix
|
||||||
|
./services/torrent.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
sbruder = {
|
sbruder = {
|
||||||
|
|
BIN
machines/fuuko/secrets/aria2-wireguard.nix
Normal file
BIN
machines/fuuko/secrets/aria2-wireguard.nix
Normal file
Binary file not shown.
|
@ -66,6 +66,14 @@ in
|
||||||
"vueko.vpn.sbruder.de:9100"
|
"vueko.vpn.sbruder.de:9100"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
job_name = "aria2";
|
||||||
|
static_configs = mkStaticTarget "127.0.0.1:9578";
|
||||||
|
relabel_configs = lib.singleton {
|
||||||
|
target_label = "instance";
|
||||||
|
replacement = "torrent.sbruder.de";
|
||||||
|
};
|
||||||
|
}
|
||||||
{
|
{
|
||||||
job_name = "fritzbox";
|
job_name = "fritzbox";
|
||||||
static_configs = mkStaticTarget "127.0.0.1:9133";
|
static_configs = mkStaticTarget "127.0.0.1:9133";
|
||||||
|
@ -113,6 +121,11 @@ in
|
||||||
for = "10m";
|
for = "10m";
|
||||||
description = "Thinkpad T440’s ACPI temperature is broken. Its reported temperature is 48 °C for the last 10 minutes. That doesn’t seem right. Try suspending";
|
description = "Thinkpad T440’s ACPI temperature is broken. Its reported temperature is 48 °C for the last 10 minutes. That doesn’t seem right. Try suspending";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
name = "TorrentNoPeers";
|
||||||
|
expr = "sum by (instance) (aria2_torrent_peers) == 0";
|
||||||
|
description = "Aria2 instance {{ $labels.instance }} has no peers. There might be a network connectivity problem";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
209
machines/fuuko/services/torrent.nix
Normal file
209
machines/fuuko/services/torrent.nix
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
{ 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 don’t 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
|
||||||
|
|
||||||
|
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
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in a new issue