Prove
This commit is contained in:
parent
4300ddacb0
commit
b80563f0ed
10 changed files with 755 additions and 1 deletions
1
lxc-nix
1
lxc-nix
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 171675dae9dd0e673416badf01ef4cc1ee33c96c
|
||||
12
lxc-nix/buildLxcImage.sh
Executable file
12
lxc-nix/buildLxcImage.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -p nixos-generators
|
||||
#! nix-shell -i bash
|
||||
set -xe
|
||||
|
||||
CONFIGURATIONNIX=$1
|
||||
METAIMG=$(nixos-generate -f lxc-metadata)
|
||||
# IMG_PROXMOX=`nixos-generate -c ${CONFIGURATIONNIX} -f proxmox-lxc`
|
||||
IMG=$(nixos-generate -c "${CONFIGURATIONNIX}" -f lxc)
|
||||
|
||||
lxc image delete nixos || echo true
|
||||
lxc image import --alias nixos "${METAIMG}" "${IMG}"
|
||||
131
lxc-nix/configuration.nix
Normal file
131
lxc-nix/configuration.nix
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
|
||||
parameters = import ./parameters.nix { };
|
||||
|
||||
# GID = 888;
|
||||
# user = "rtorrent";
|
||||
# passwordHash = "$y$j9T$dA94KVg1/jYLqclQQbTDk.$cnfxBWUN8P4shr8Kkipv5bU/RCtQNoAwYFDZ0X/BYs5";
|
||||
|
||||
timeZone = "Europe/Rome";
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
||||
# Need to load some defaults for running in an lxc container.
|
||||
# This is explained in:
|
||||
# https://github.com/nix-community/nixos-generators/issues/79
|
||||
# "${modulesPath}/virtualisation/lxc-container.nix"
|
||||
|
||||
# ./modules/qbittorrent.nix
|
||||
#./modules/rutorrent.nix
|
||||
|
||||
# ./services/qbittorrent.nix
|
||||
#./services/rutorrent.nix
|
||||
./services/networking.nix
|
||||
];
|
||||
|
||||
# This doesn't do _everything_ we need, because `boot.isContainer` is
|
||||
# specifically talking about light-weight NixOS containers, not LXC. But it
|
||||
# does at least gives us something to start with.
|
||||
boot.isContainer = true;
|
||||
|
||||
networking = {
|
||||
hostName = parameters.containerName;
|
||||
};
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# Extra packages
|
||||
# environment.systemPackages = with pkgs; [ ];
|
||||
|
||||
services = {
|
||||
openssh.enable = true;
|
||||
tailscale = {
|
||||
enable = false;
|
||||
useRoutingFeatures = "both";
|
||||
extraUpFlags = [ "--exit-node=${parameters.tailscaleExitNodeIP}" ];
|
||||
authKeyFile = builtins.toFile "authKey" ''${parameters.tailscaleAuthKey}'';
|
||||
};
|
||||
};
|
||||
|
||||
time.timeZone = parameters.timeZone;
|
||||
|
||||
i18n = {
|
||||
defaultLocale = defaultLocale;
|
||||
extraLocaleSettings = {
|
||||
LC_ADDRESS = defaultLocale;
|
||||
LC_IDENTIFICATION = defaultLocale;
|
||||
LC_MEASUREMENT = defaultLocale;
|
||||
LC_MONETARY = defaultLocale;
|
||||
LC_NAME = defaultLocale;
|
||||
LC_PAPER = defaultLocale;
|
||||
LC_TELEPHONE = defaultLocale;
|
||||
# LC_NUMERIC = defaultLocale;
|
||||
# LC_TIME = defaultLocale;
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
|
||||
# If set to false, the contents of the user and group files will simply
|
||||
# be replaced on system activation.
|
||||
# This also holds for the user passwords.
|
||||
# All changed passwords will be reset according
|
||||
# to the `users.users` configuration on activation.
|
||||
mutableUsers = false;
|
||||
|
||||
users.root = {
|
||||
hashedPassword = "$6$gir1YD6tNdC9xAj0$zLr1yt/ea9PvwygjHfQVnPmeCd1.2zrAKWiN80duidwOkZF6hwm06ta6J3O9uw6F3uUHC0N7iiKYhCgXXR.Q7/";
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDhiGLc/whCY3lCmDiRlYnMJOLiO/gvcRj/sKVEFVAhQ pazpi@deadbeef"
|
||||
];
|
||||
};
|
||||
|
||||
users.pazpi = {
|
||||
isNormalUser = true;
|
||||
shell = pkgs.bash;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDhiGLc/whCY3lCmDiRlYnMJOLiO/gvcRj/sKVEFVAhQ pazpi@deadbeef"
|
||||
];
|
||||
};
|
||||
|
||||
# groups = {
|
||||
# qbittorrent = { gid = GID; };
|
||||
# };
|
||||
|
||||
# users."${user}" = {
|
||||
# isNormalUser = true;
|
||||
# group = "qbittorrent";
|
||||
# extraGroups = [ "user" "multimedia" ];
|
||||
# # initialHashedPassword = passwordHash;
|
||||
# };
|
||||
};
|
||||
|
||||
# # Enable passwordless sudo.
|
||||
# security.sudo.extraRules = [
|
||||
# {
|
||||
# users = [ user ];
|
||||
# commands = [
|
||||
# {
|
||||
# command = "ALL";
|
||||
# options = [ "NOPASSWD" ];
|
||||
# }
|
||||
# ];
|
||||
# }
|
||||
# ];
|
||||
|
||||
# Supress systemd units that don't work because of LXC.
|
||||
# https://blog.xirion.net/posts/nixos-proxmox-lxc/#configurationnix-tweak
|
||||
systemd.suppressedSystemUnits = [
|
||||
"dev-mqueue.mount"
|
||||
"sys-kernel-debug.mount"
|
||||
"sys-fs-fuse-connections.mount"
|
||||
];
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
}
|
||||
126
lxc-nix/modules/qbittorrent.nix
Normal file
126
lxc-nix/modules/qbittorrent.nix
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.qbittorrent;
|
||||
UID = 888;
|
||||
GID = 888;
|
||||
in
|
||||
{
|
||||
options.services.qbittorrent = {
|
||||
enable = mkEnableOption (lib.mdDoc "qBittorrent headless");
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
The directory where qBittorrent stores its data files.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
User account under which qBittorrent runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
Group under which qBittorrent runs.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8080;
|
||||
description = lib.mdDoc ''
|
||||
qBittorrent web UI port.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Open services.qBittorrent.port to the outside network.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.qbittorrent-nox;
|
||||
defaultText = literalExpression "pkgs.qbittorrent-nox";
|
||||
description = lib.mdDoc ''
|
||||
The qbittorrent package to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
systemd.services.qbittorrent = {
|
||||
# based on the plex.nix service module and
|
||||
# https://github.com/qbittorrent/qBittorrent/blob/master/dist/unix/systemd/qbittorrent-nox%40.service.in
|
||||
description = "qBittorrent-nox service";
|
||||
documentation = [ "man:qbittorrent-nox(1)" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
||||
# Run the pre-start script with full permissions (the "!" prefix) so it
|
||||
# can create the data directory if necessary.
|
||||
ExecStartPre =
|
||||
let
|
||||
preStartScript = pkgs.writeScript "qbittorrent-run-prestart" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
# Create data directory if it doesn't exist
|
||||
if ! test -d "$QBT_PROFILE"; then
|
||||
echo "Creating initial qBittorrent data directory in: $QBT_PROFILE"
|
||||
install -d -m 0755 -o "${cfg.user}" -g "${cfg.group}" "$QBT_PROFILE"
|
||||
fi
|
||||
'';
|
||||
in
|
||||
"!${preStartScript}";
|
||||
|
||||
#ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox";
|
||||
ExecStart = "${cfg.package}/bin/qbittorrent-nox";
|
||||
# To prevent "Quit & shutdown daemon" from working; we want systemd to
|
||||
# manage it!
|
||||
#Restart = "on-success";
|
||||
#UMask = "0002";
|
||||
#LimitNOFILE = cfg.openFilesLimit;
|
||||
};
|
||||
|
||||
environment = {
|
||||
QBT_PROFILE = cfg.dataDir;
|
||||
QBT_WEBUI_PORT = toString cfg.port;
|
||||
QBT_EULA = "accept";
|
||||
# QBT_EULA = toString cfg.acceptEula;
|
||||
};
|
||||
};
|
||||
|
||||
# users.users = mkIf (cfg.user == "qbittorrent") {
|
||||
# qbittorrent = {
|
||||
# group = cfg.group;
|
||||
# uid = UID;
|
||||
# };
|
||||
# };
|
||||
|
||||
# users.groups = mkIf (cfg.group == "qbittorrent") {
|
||||
# qbittorrent = { gid = GID; };
|
||||
# };
|
||||
};
|
||||
}
|
||||
325
lxc-nix/modules/rutorrent.nix
Normal file
325
lxc-nix/modules/rutorrent.nix
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.rutorrent;
|
||||
|
||||
rutorrentPkgs = import ../packages/rutorrent.nix { inherit pkgs; inherit lib; };
|
||||
|
||||
rtorrentPluginDependencies = with pkgs; {
|
||||
_task = [ procps ];
|
||||
unpack = [ unzip unrar ];
|
||||
rss = [ curl ];
|
||||
mediainfo = [ mediainfo ];
|
||||
spectrogram = [ sox ];
|
||||
screenshots = [ ffmpeg ];
|
||||
};
|
||||
|
||||
phpPluginDependencies = with pkgs; {
|
||||
_cloudflare = [ python3 ];
|
||||
};
|
||||
|
||||
getPluginDependencies = dependencies: concatMap (p: attrByPath [ p ] [ ] dependencies);
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.rutorrent = {
|
||||
enable = mkEnableOption "ruTorrent";
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
description = "FQDN for the ruTorrent instance.";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/rutorrent";
|
||||
description = "Storage path of ruTorrent.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "rutorrent";
|
||||
description = ''
|
||||
User which runs the ruTorrent service.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "rutorrent";
|
||||
description = ''
|
||||
Group which runs the ruTorrent service.
|
||||
'';
|
||||
};
|
||||
|
||||
rpcSocket = mkOption {
|
||||
type = types.str;
|
||||
default = config.services.rtorrent.rpcSocket;
|
||||
defaultText = "config.services.rtorrent.rpcSocket";
|
||||
description = ''
|
||||
Path to rtorrent rpc socket.
|
||||
'';
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = with types; listOf (either str package);
|
||||
default = [ "httprpc" ];
|
||||
example = literalExample ''[ "httprpc" "data" "diskspace" "edit" "erasedata" "theme" "trafic" ]'';
|
||||
description = ''
|
||||
List of plugins to enable. See the list of <link xlink:href="https://github.com/Novik/ruTorrent/wiki/Plugins#currently-there-are-the-following-plugins">available plugins</link>. Note: the <literal>unpack</literal> plugin needs the nonfree <literal>unrar</literal> package.
|
||||
You need to either enable one of the <literal>rpc</literal> or <literal>httprpc</literal> plugin or enable the <xref linkend="opt-services.rutorrent.nginx.exposeInsecureRPC2mount"/> option.
|
||||
'';
|
||||
};
|
||||
|
||||
poolSettings = mkOption {
|
||||
type = with types; attrsOf (oneOf [ str int bool ]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 4;
|
||||
"pm.max_requests" = 500;
|
||||
};
|
||||
description = ''
|
||||
Options for ruTorrent's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable nginx virtual host management.
|
||||
Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.<name></literal>.
|
||||
See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
|
||||
'';
|
||||
};
|
||||
|
||||
exposeInsecureRPC2mount = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If you do not enable one of the <literal>rpc</literal> or <literal>httprpc</literal> plugins you need to expose an RPC mount through scgi using this option.
|
||||
Warning: This allow to run arbitrary commands, as the rtorrent user, so make sure to use authentification. The simplest way would be to use the <literal>services.nginx.virtualHosts.<name>.basicAuth</literal> option.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions =
|
||||
let
|
||||
usedRpcPlugins = intersectLists cfg.plugins [ "httprpc" "rpc" ];
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = (length usedRpcPlugins < 2);
|
||||
message = "Please specify only one of httprpc or rpc plugins";
|
||||
}
|
||||
{
|
||||
assertion = !(length usedRpcPlugins > 0 && cfg.nginx.exposeInsecureRPC2mount);
|
||||
message = "Please do not use exposeInsecureRPC2mount if you use one of httprpc or rpc plugins";
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
let
|
||||
nginxVhostCfg = config.services.nginx.virtualHosts."${cfg.hostName}";
|
||||
in
|
||||
[ ]
|
||||
++ (optional (cfg.nginx.exposeInsecureRPC2mount && (nginxVhostCfg.basicAuth == { } || nginxVhostCfg.basicAuthFile == null)) ''
|
||||
You are using exposeInsecureRPC2mount without using basic auth on the virtual host. The exposed rpc mount allow for remote command execution.
|
||||
|
||||
Please make sure it is not accessible from the outside.
|
||||
'');
|
||||
|
||||
systemd = {
|
||||
services = {
|
||||
rtorrent.path = getPluginDependencies rtorrentPluginDependencies cfg.plugins;
|
||||
rutorrent-setup =
|
||||
let
|
||||
rutorrentConfig = pkgs.writeText "rutorrent-config.php" ''
|
||||
<?php
|
||||
// configuration parameters
|
||||
|
||||
// for snoopy client
|
||||
@define('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36', true);
|
||||
@define('HTTP_TIME_OUT', 30, true); // in seconds
|
||||
@define('HTTP_USE_GZIP', true, true);
|
||||
$httpIP = null; // IP string. Or null for any.
|
||||
$httpProxy = array
|
||||
(
|
||||
'use' => false,
|
||||
'proto' => 'http', // 'http' or 'https'
|
||||
'host' => 'PROXY_HOST_HERE',
|
||||
'port' => 3128
|
||||
);
|
||||
|
||||
@define('RPC_TIME_OUT', 5, true); // in seconds
|
||||
|
||||
@define('LOG_RPC_CALLS', false, true);
|
||||
@define('LOG_RPC_FAULTS', true, true);
|
||||
|
||||
// for php
|
||||
@define('PHP_USE_GZIP', false, true);
|
||||
@define('PHP_GZIP_LEVEL', 2, true);
|
||||
|
||||
$schedule_rand = 10; // rand for schedulers start, +0..X seconds
|
||||
|
||||
$do_diagnostic = true;
|
||||
$log_file = '${cfg.dataDir}/logs/errors.log'; // path to log file (comment or leave blank to disable logging)
|
||||
|
||||
$saveUploadedTorrents = true; // Save uploaded torrents to profile/torrents directory or not
|
||||
$overwriteUploadedTorrents = false; // Overwrite existing uploaded torrents in profile/torrents directory or make unique name
|
||||
|
||||
$topDirectory = '/'; // Upper available directory. Absolute path with trail slash.
|
||||
$forbidUserSettings = false;
|
||||
|
||||
$scgi_port = 0;
|
||||
$scgi_host = "unix://${cfg.rpcSocket}";
|
||||
|
||||
$XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!!
|
||||
|
||||
$pathToExternals = array(
|
||||
"php" => "${pkgs.php}/bin/php", // Something like /usr/bin/php. If empty, will be found in PATH.
|
||||
"curl" => "${pkgs.curl}/bin/curl", // Something like /usr/bin/curl. If empty, will be found in PATH.
|
||||
"gzip" => "${pkgs.gzip}/bin/gzip", // Something like /usr/bin/gzip. If empty, will be found in PATH.
|
||||
"id" => "${pkgs.coreutils}/bin/id", // Something like /usr/bin/id. If empty, will be found in PATH.
|
||||
"stat" => "${pkgs.coreutils}/bin/stat", // Something like /usr/bin/stat. If empty, will be found in PATH.
|
||||
"pgrep" => "${pkgs.procps}/bin/pgrep", // TODO why can't we use phpEnv.PATH
|
||||
);
|
||||
|
||||
$localhosts = array( // list of local interfaces
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
);
|
||||
|
||||
$profilePath = '${cfg.dataDir}/share'; // Path to user profiles
|
||||
$profileMask = 0770; // Mask for files and directory creation in user profiles.
|
||||
// Both Webserver and rtorrent users must have read-write access to it.
|
||||
// For example, if Webserver and rtorrent users are in the same group then the value may be 0770.
|
||||
|
||||
$tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used.
|
||||
|
||||
$canUseXSendFile = false; // If true then use X-Sendfile feature if it exist
|
||||
|
||||
$locale = "UTF8";
|
||||
|
||||
$throttleMaxSpeed = 327625*1024;
|
||||
'';
|
||||
in
|
||||
{
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "phpfpm-rutorrent.service" ];
|
||||
script = ''
|
||||
ln -sf ${rutorrentPkgs}/{css,images,js,lang,index.html} ${cfg.dataDir}/
|
||||
mkdir -p ${cfg.dataDir}/{conf,logs,plugins} ${cfg.dataDir}/share/{settings,torrents,users}
|
||||
ln -sf ${rutorrentPkgs}/conf/{access.ini,plugins.ini} ${cfg.dataDir}/conf/
|
||||
ln -sf ${rutorrentConfig} ${cfg.dataDir}/conf/config.php
|
||||
|
||||
cp -r ${rutorrentPkgs}/php ${cfg.dataDir}/
|
||||
|
||||
${optionalString (cfg.plugins != [])
|
||||
''cp -r ${concatMapStringsSep " " (p: "${rutorrentPkgs}/plugins/${p}") cfg.plugins} ${cfg.dataDir}/plugins/''}
|
||||
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}/{conf,share,logs,plugins}
|
||||
chmod -R 755 ${cfg.dataDir}/{conf,share,logs,plugins}
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
tmpfiles.rules = [ "d '${cfg.dataDir}' 0775 ${cfg.user} ${cfg.group} -" ];
|
||||
};
|
||||
|
||||
users.groups."${cfg.group}" = { };
|
||||
|
||||
users.users = {
|
||||
"${cfg.user}" = {
|
||||
home = cfg.dataDir;
|
||||
group = cfg.group;
|
||||
extraGroups = [ config.services.rtorrent.group ];
|
||||
description = "ruTorrent Daemon user";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
"${config.services.rtorrent.user}" = {
|
||||
extraGroups = [ cfg.group ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf cfg.nginx.enable (mkMerge [
|
||||
{
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 80 443 ];
|
||||
};
|
||||
|
||||
services = {
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
user = cfg.user;
|
||||
group = cfg.group;
|
||||
virtualHosts = {
|
||||
${cfg.hostName} = {
|
||||
root = cfg.dataDir;
|
||||
locations = {
|
||||
"~ [^/]\.php(/|$)" = {
|
||||
extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Mitigate https://httpoxy.org/ vulnerabilities
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.rutorrent.socket};
|
||||
fastcgi_index index.php;
|
||||
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
phpfpm.pools.rutorrent =
|
||||
let
|
||||
envPath = lib.makeBinPath (getPluginDependencies phpPluginDependencies cfg.plugins);
|
||||
pool = {
|
||||
user = cfg.user;
|
||||
group = config.services.rtorrent.group;
|
||||
settings = mapAttrs (name: mkDefault)
|
||||
{
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"listen.group" = config.services.nginx.group;
|
||||
} // cfg.poolSettings;
|
||||
};
|
||||
in
|
||||
if (envPath == "") then pool else pool // { phpEnv.PATH = envPath; };
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf cfg.nginx.exposeInsecureRPC2mount {
|
||||
services.nginx.virtualHosts."${cfg.hostName}".locations."/RPC2" = {
|
||||
extraConfig = ''
|
||||
include ${pkgs.nginx}/conf/scgi_params;
|
||||
scgi_pass unix:${cfg.rpcSocket};
|
||||
'';
|
||||
};
|
||||
})
|
||||
]))
|
||||
]);
|
||||
}
|
||||
27
lxc-nix/packages/rutorrent.nix
Normal file
27
lxc-nix/packages/rutorrent.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{ pkgs ? import <nixpkgs> { }, lib, }:
|
||||
|
||||
with pkgs;
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "rutorrent";
|
||||
version = "4.2.9";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Novik";
|
||||
repo = "ruTorrent";
|
||||
rev = "v${version}";
|
||||
sha256 = "qgtP8IOJ5R8IWXf34MSa5WiH68oRG2j/IjGC2TPfQc0=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/
|
||||
cp -r . $out/
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Yet another web front-end for rTorrent";
|
||||
homepage = "https://github.com/Novik/ruTorrent";
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
}
|
||||
10
lxc-nix/parameters.nix
Normal file
10
lxc-nix/parameters.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ ... }:
|
||||
{
|
||||
containerName = "nixos-test"; # Name of the container, used for nginx virtualhost and for tailscale machine name
|
||||
timeZone = "Europe/Rome"; # TimeZone
|
||||
|
||||
downloadDir = "/mnt/data"; # Main download folder
|
||||
|
||||
tailscaleAuthKey = "tskey-auth-kmgDY87CNTRL-urQA7eRn235t8Sjs6hW3259wJHE63Kvd";
|
||||
tailscaleExitNodeIP = "100.81.1.32"; # vps
|
||||
}
|
||||
26
lxc-nix/services/networking.nix
Normal file
26
lxc-nix/services/networking.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ ... }:
|
||||
{
|
||||
|
||||
networking = {
|
||||
|
||||
# If you prefer DHCP
|
||||
# interfaces.eth0.useDHCP = true;
|
||||
|
||||
# We don't use DHCP, so we configure it statically.
|
||||
interfaces.eth0.ipv4.addresses = [{
|
||||
address = "10.42.135.101";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
|
||||
# We can access the internet through this interface.
|
||||
defaultGateway = {
|
||||
address = "10.42.135.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
|
||||
# Since we don't use DHCP, we need to set our own nameservers.
|
||||
nameservers = [ "1.1.1.1" "1.0.0.1" ];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
29
lxc-nix/services/qbittorrent.nix
Normal file
29
lxc-nix/services/qbittorrent.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# qBittorrent service activation
|
||||
#
|
||||
# The shell script 'fixdlperms' is also created and should be added to the
|
||||
# "Run external program on finished" section with the full path:
|
||||
# /run/current-system/sw/bin/fixdlperms
|
||||
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
downloadDir = "/data/multimedia/downloads";
|
||||
fixDownloadPerms = pkgs.writeShellScriptBin "fixdlperms" ''
|
||||
find ${downloadDir} -type d -exec chmod 2775 {} +
|
||||
find ${downloadDir} -type f -exec chmod 0664 {} +
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.qbittorrent = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
dataDir = "/srv/qbittorrent";
|
||||
port = 58080;
|
||||
user = "qbittorrent";
|
||||
};
|
||||
|
||||
# Allow qbittorrent to save files in the multimedia share
|
||||
# users.users.qbittorrent.extraGroups = [ "multimedia" ];
|
||||
|
||||
environment.systemPackages = [ fixDownloadPerms ];
|
||||
}
|
||||
69
lxc-nix/services/rutorrent.nix
Normal file
69
lxc-nix/services/rutorrent.nix
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
parameters = import ../parameters.nix { };
|
||||
in
|
||||
{
|
||||
services = {
|
||||
|
||||
rtorrent = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
downloadDir = parameters.downloadDir;
|
||||
};
|
||||
|
||||
rutorrent = {
|
||||
enable = true;
|
||||
hostName = parameters.containerName;
|
||||
plugins = [
|
||||
"_cloudflare"
|
||||
"_getdir"
|
||||
"_noty2"
|
||||
"_task"
|
||||
"autotools"
|
||||
"check_port"
|
||||
"chunks"
|
||||
"cookies"
|
||||
"cpuload"
|
||||
# "сreate"
|
||||
"data"
|
||||
"datadir"
|
||||
"diskspace"
|
||||
"edit"
|
||||
"erasedata"
|
||||
"extratio"
|
||||
"extsearch"
|
||||
"feeds"
|
||||
"filedrop"
|
||||
"geoip"
|
||||
"history"
|
||||
"httprpc"
|
||||
"ipad"
|
||||
"loginmgr"
|
||||
"lookat"
|
||||
"mediainfo"
|
||||
"ratio"
|
||||
"retrackers"
|
||||
"rss"
|
||||
"rssurlrewrite"
|
||||
"rutracker_check"
|
||||
"scheduler"
|
||||
"screenshots"
|
||||
"seedingtime"
|
||||
"show_peers_like_wtorrent"
|
||||
"source"
|
||||
"spectrogram"
|
||||
"theme"
|
||||
"throttle"
|
||||
"tracklabels"
|
||||
"trafic"
|
||||
"unpack"
|
||||
"uploadeta"
|
||||
];
|
||||
nginx = {
|
||||
enable = true;
|
||||
# exposeInsecureRPC2mount = true;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue