Compare commits

...

6 commits

Author SHA1 Message Date
ee1139713c hosts: nixos: porthos: services: enable cross-seed
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-16 17:26:10 +02:00
058096079e hosts: nixos: porthos: secrets: add cross-seed 2025-04-16 17:26:10 +02:00
c40090d176 nixos: services: servarr: add cross-seed 2025-04-16 17:26:10 +02:00
1b6a48d6c2 flake: bump inputs 2025-04-16 17:07:38 +02:00
e4bc0444bf nixos: services: transmission: fix umask
I want downloads to be readable by the `media` group. The permissions
weren't correctly applied without `umask`.
2025-04-16 17:01:18 +02:00
c69aaa7adb nixos: services: servarr: autobrr: fix websockets
I found some logs complaining about websockets before enabling this.
2025-04-16 17:01:18 +02:00
8 changed files with 107 additions and 3 deletions

6
flake.lock generated
View file

@ -175,11 +175,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1744174375,
"narHash": "sha256-oxI9TLgnQbQ/WL0tIwVSIooLbXq4PW1QUhf5aQmXFgk=",
"lastModified": 1744777043,
"narHash": "sha256-O6jgTxz9BKUiaJl03JsVHvSjtCOC8gHfDvC2UCfcLMc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ef3a956f697525883b77192cbe208233ea0f8f79",
"rev": "7a6f7f4c1c69eee05641beaa40e7f85da8e69fb0",
"type": "github"
},
"original": {

View file

@ -81,6 +81,7 @@ in
"pyload/credentials.age".publicKeys = all;
"servarr/autobrr/session-secret.age".publicKeys = all;
"servarr/cross-seed/configuration.json.age".publicKeys = all;
"sso/auth-key.age" = {
owner = "nginx-sso";

View file

@ -148,6 +148,9 @@ in
autobrr = {
sessionSecretFile = secrets."servarr/autobrr/session-secret".path;
};
cross-seed = {
secretSettingsFile = secrets."servarr/cross-seed/configuration.json".path;
};
# ... But not Lidarr because I don't care for music that much
lidarr = {
enable = false;

View file

@ -40,6 +40,7 @@ in
my.services.nginx.virtualHosts = {
autobrr = {
inherit (cfg) port;
websocketsLocations = [ "/api" ];
};
};

View file

@ -0,0 +1,96 @@
# Automatic cross-seeding for video media
{ config, lib, ... }:
let
cfg = config.my.services.servarr.cross-seed;
in
{
options.my.services.servarr.cross-seed = with lib; {
enable = mkEnableOption "cross-seed daemon" // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = 2468;
example = 8080;
description = "Internal port for daemon";
};
linkDirectory = mkOption {
type = types.str;
default = "/data/downloads/complete/links";
example = "/var/lib/cross-seed/links";
description = "Link directory";
};
secretSettingsFile = mkOption {
type = types.str;
example = "/run/secrets/cross-seed-secrets.json";
description = ''
File containing secret settings.
'';
};
};
config = lib.mkIf cfg.enable {
services.cross-seed = {
enable = true;
group = "media";
# Rely on recommended defaults for tracker snatches etc...
useGenConfigDefaults = true;
settings = {
inherit (cfg) port;
host = "127.0.0.1";
# Inject torrents to client directly
action = "inject";
# Query the client for torrents to match
useClientTorrents = true;
# Use hardlinks
linkType = "hardlink";
# Use configured link directory
linkDirs = [ cfg.linkDirectory ];
# Match as many torrents as possible
matchMode = "partial";
# Cross-seed full season if at least 50% of episodes are already downloaded
seasonFromEpisodes = 0.5;
};
settingsFile = cfg.secretSettingsFile;
};
systemd.services.cross-seed = {
serviceConfig = {
# Loose umask to make cross-seed links readable by `media`
UMask = "0002";
};
};
# Set-up media group
users.groups.media = { };
my.services.nginx.virtualHosts = {
cross-seed = {
inherit (cfg) port;
};
};
services.fail2ban.jails = {
cross-seed = ''
enabled = true
filter = cross-seed
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/cross-seed.conf".text = ''
[Definition]
failregex = ^.*Unauthorized API access attempt to .* from <HOST>$
journalmatch = _SYSTEMD_UNIT=cross-seed.service
'';
};
};
}

View file

@ -7,6 +7,7 @@
imports = [
./autobrr.nix
./bazarr.nix
./cross-seed.nix
./jackett.nix
./nzbhydra.nix
./prowlarr.nix

View file

@ -65,6 +65,8 @@ in
# Proxied behind Nginx.
rpc-whitelist-enabled = true;
rpc-whitelist = "127.0.0.1";
umask = "002"; # To go with `downloadDirPermissions`
};
};