transmission works but is not nice

This commit is contained in:
Ingolf Wagner 2021-12-29 19:46:20 +01:00
parent ee9ff1306d
commit 9d34f3321f
No known key found for this signature in database
GPG key ID: 76BF5F1928B9618B
6 changed files with 211 additions and 112 deletions

View file

@ -62,7 +62,7 @@
"secrets": {
"flake": false,
"locked": {
"narHash": "sha256-nl0nvXupyQ5mIdc9pVd0quWZwDJNcudUcbusp8Im+cM=",
"narHash": "sha256-OlWM45xthVFn2NnXrIYRslLFt1m+q2ytMuasN8zXfNs=",
"path": "/home/palo/dev/secrets",
"type": "path"
},

View file

@ -6,17 +6,19 @@
./hetzner.nix
#./nextcloud.nix
# todo
./nextcloud.nix
./packages.nix
./tinc.nix
./syncthing.nix
./taskserver.nix
./transmission.nix
#../../system/server
#./hardware-configuration.nix
#./mail-fetcher.nix
#./transmission.nix
#./borg.nix
#./finance.nix
#./gogs.nix
@ -26,12 +28,18 @@
#./kibana.nix
#./mysql.nix
#./prometheus.nix
#./taskserver.nix
#./weechat.nix
#./property.nix # flask sucks, find something else
];
# Shell configuration
# -------------------
programs.custom = {
bash.enable = true;
zsh.enable = true;
};
security.acme = {
acceptTerms = true;
email = "contact@ingolf-wagner.de";

View file

@ -1,10 +1,16 @@
{ pkgs, config, lib, ... }:
let
nextcloudUid = 1000;
in
{
users.users.nextcloud = {
isSystemUser = true;
uid = nextcloudUid;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedUDPPorts = [ 80 443 ];
#networking.firewall.allowedTCPPorts = [ 80 443 ];
#networking.firewall.allowedUDPPorts = [ 80 443 ];
# host nginx setup
services.nginx = {
@ -13,16 +19,15 @@
recommendedOptimisation = lib.mkDefault true;
recommendedTlsSettings = lib.mkDefault true;
recommendedProxySettings = true;
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
#sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
virtualHosts = {
"nextcloud.ingolf-wagner.de" = {
forceSSL = true;
enableACME = true;
#virtualHosts = {
# "nextcloud.ingolf-wagner.de" = {
# forceSSL = true;
# enableACME = true;
# };
#};
};
};
};
# nextcloud database
# ==================
@ -45,6 +50,15 @@
# -------------
# https://docs.nextcloud.com/server/18/admin_manual/configuration_database/mysql_4byte_support.html
# if you do this don't forget --default-character-set=utf8mb4 for mysqldump
containers.nextcloudmysql = {
autoStart = true;
forwardPorts = [{
containerPort = 3336;
hostPort = 3336;
protocol = "tcp";
}];
config = { config, pkgs, lib, ... }: {
services.mysql = {
enable = true;
package = pkgs.mysql;
@ -63,26 +77,29 @@
# Backup database
# ---------------
services.mysqlBackup = {
enable = true;
databases = config.services.mysql.ensureDatabases;
singleTransaction = true;
location = "/var/lib/nextcloud/database_backups";
#services.mysqlBackup = {
# enable = true;
# databases = config.services.mysql.ensureDatabases;
# singleTransaction = true;
# location = "/var/lib/nextcloud/database_backups";
#};
#systemd.services."mysql-backup".serviceConfig = {
# ExecStartPre = [ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --on" ];
# ExecStopPost = [ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --off" ];
#};
};
systemd.services."mysql-backup".serviceConfig = {
ExecStartPre =
[ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --on" ];
ExecStopPost = [
"+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --off"
];
};
# in php
services.phpfpm.phpPackage = pkgs.php73;
# nextcloud setup
services.nextcloud = {
enable = true;
enable = false;
hostName = "nextcloud.ingolf-wagner.de";
package = pkgs.nextcloud22;
autoUpdateApps.enable = true;

View file

@ -109,7 +109,7 @@
system.permown."/media/syncthing" = {
owner = "syncthing";
group = "syncthing";
umask = "0022";
umask = "0002";
};
systemd.services."permown._media_syncthing" = {
bindsTo = [ "media.mount" ];

View file

@ -11,6 +11,9 @@
ciphers = "SECURE256";
};
backup.dirs = [ config.services.taskserver.dataDir ];
networking.firewall.allowedTCPPorts = [ config.services.taskserver.listenPort ];
networking.firewall.allowedUDPPorts = [ config.services.taskserver.listenPort ];
#backup.dirs = [ config.services.taskserver.dataDir ];
}

View file

@ -1,9 +1,75 @@
{ pkgs, config, ... }:
{ lib, pkgs, config, ... }:
#
# cp -avl (to create hardlinks instead of copy)
# =============================================
#
#┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
#│/media/torrent/downloads/music ├─────►│/media/syncthing/music/incomming │
#└──────────────────────────────────┘ └──────────────────────────────────────┘
#┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
#│/media/torrent/downloads/movies ├─────►│/media/syncthing/movies/incoming │
#└──────────────────────────────────┘ └──────────────────────────────────────┘
#┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
#│/media/torrent/downloads ├─────►│/media/torrent/incoming │
#└──────────────────────────────────┘ └──────────────────────────────────────┘
let
hostInterface = "enp3s0";
hostAddress = "192.168.100.30";
containerAddress = "192.168.100.31";
uiPort = 9091;
#############################################
# These are inherited from Transmission. #
# Do not declare these. Just use as needed. #
# #
# TR_APP_VERSION #
# TR_TIME_LOCALTIME #
# TR_TORRENT_DIR #
# TR_TORRENT_HASH #
# TR_TORRENT_ID #
# TR_TORRENT_NAME #
# #
#############################################
completionScript = let
copy_map = {
"/media/torrent/downloads/movies" = "/media/syncthing/movies/incoming";
"/media/torrent/downloads" = "/media/torrent/incoming";
};
copy_script = lib.concatStringsSep "\n" (lib.mapAttrsToList (source: target: ''
if [[ "$TR_TORRENT_DIR" == "${source}" ]]
then
cp -val "$TR_TORRENT_DIR/$TR_TORRENT_NAME" "${target}/$TR_TORRENT_NAME"
fi
'') copy_map);
in
pkgs.writers.writeBash "torrent-finished" ''
${copy_script}
${pkgs.jq}/bin/jq '{
"token": "'"$PUSHOVER_API_KEY"'",
"user": "'"$PUSHOVER_USER_KEY"'",
"titel": "transmission",
"message": "'"$TR_TORRENT_NAME finished"'"
}' >> /media/torrent/finish.log
${pkgs.jq}/bin/jq '{
"token": "'"$PUSHOVER_API_KEY"'",
"user": "'"$PUSHOVER_USER_KEY"'",
"titel": "transmission",
"message": "'"$TR_TORRENT_NAME finished"'"
}' \
| ${pkgs.curl}/bin/curl \
-sS \
-X POST \
-H 'Content-Type: application/json' \
-d @- \
https://api.pushover.net/1/messages.json
'';
in
{
@ -13,6 +79,7 @@ in
#};
sops.secrets.nordvpn = { };
sops.secrets.transmissionPushover= { };
containers.torrent = {
@ -23,24 +90,23 @@ in
# mountPoint = "/run/secrets/transmission_password";
# isReadOnly = true;
#};
transmissionPushover = {
hostPath = "/run/secrets/transmissionPushover";
mountPoint = "/run/secrets/transmissionPushover";
isReadOnly = true;
};
nordvpnPassword = {
hostPath = "/run/secrets/nordvpn";
mountPoint = "/run/secrets/nordvpn";
isReadOnly = true;
};
home = {
hostPath = "/home/torrent";
mountPoint = "/home/torrent";
isReadOnly = false;
};
media = {
hostPath = "/media";
mountPoint =
"/home/torrent/downloads/media"; # must be here otherwise transmission can't see the folder
mountPoint = "/media"; # must be here otherwise transmission can't see the folder
isReadOnly = false;
};
lib = {
hostPath = "/home/torrent/.config";
hostPath = "/media/torrent/.config";
mountPoint = "/var/lib/transmission/.config";
isReadOnly = false;
};
@ -52,57 +118,61 @@ in
hostAddress = hostAddress;
localAddress = containerAddress;
autoStart = true;
# needed for openvpn
enableTun = true;
config = { config, pkgs, lib, ... }: {
services.journalbeat = {
enable = true;
extraConfig = ''
journalbeat.inputs:
- paths: []
# Position to start reading from journal. Valid values: head, tail, cursor
seek: cursor
# Fallback position if no cursor data is available.
cursor_seek_fallback: tail
output.logstash:
# Boolean flag to enable or disable the output module.
enabled: true
# Graylog host and the beats input
hosts: ["${hostAddress}:5044"]
# If enabled only a subset of events in a batch of events is transferred per
# transaction. The number of events to be sent increases up to `bulk_max_size`
# if no error is encountered.
slow_start: true
# The number of seconds to wait before trying to reconnect to Graylog
# after a network error. After waiting backoff.init seconds, the Beat
# tries to reconnect. If the attempt fails, the backoff timer is increased
# exponentially up to backoff.max. After a successful connection, the backoff
# timer is reset. The default is 1s.
backoff.init: 1s
# The maximum number of seconds to wait before attempting to connect to
# Graylog after a network error. The default is 60s.
backoff.max: 60s
'';
};
#services.journalbeat = {
# enable = true;
# extraConfig = ''
# journalbeat.inputs:
# - paths: []
# # Position to start reading from journal. Valid values: head, tail, cursor
# seek: cursor
# # Fallback position if no cursor data is available.
# cursor_seek_fallback: tail
# output.logstash:
# # Boolean flag to enable or disable the output module.
# enabled: true
# # Graylog host and the beats input
# hosts: ["${hostAddress}:5044"]
# # If enabled only a subset of events in a batch of events is transferred per
# # transaction. The number of events to be sent increases up to `bulk_max_size`
# # if no error is encountered.
# slow_start: true
# # The number of seconds to wait before trying to reconnect to Graylog
# # after a network error. After waiting backoff.init seconds, the Beat
# # tries to reconnect. If the attempt fails, the backoff timer is increased
# # exponentially up to backoff.max. After a successful connection, the backoff
# # timer is reset. The default is 1s.
# backoff.init: 1s
# # The maximum number of seconds to wait before attempting to connect to
# # Graylog after a network error. The default is 60s.
# backoff.max: 60s
# '';
#};
services.journald.extraConfig = "SystemMaxUse=1G";
# allow transmission to write in syncthing folders
users.groups.syncthing = {
gid = config.ids.gids.syncthing;
members = ["transmission"];
};
services.transmission = {
enable = true;
settings = {
download-dir = "/home/torrent/downloads";
incomplete-dir = "/home/torrent/incomplete";
download-dir = "/media/torrent/downloads";
incomplete-dir = "/media/torrent/incomplete";
incomplete-dir-enabled = true;
message-level = 1;
umask = "002";
rpc-whitelist-enabled = false;
rpc-host-whitelist-enabled = false;
rpc-port = 9091;
rpc-port = uiPort;
rpc-enable = true;
rpc-bind-address = "0.0.0.0";
@ -110,7 +180,7 @@ in
speed-limit-down-enabled = false;
speed-limit-down = 800;
speed-limit-up-enabled = true;
speed-limit-up = 50;
speed-limit-up = 3000;
upload-slots-per-torrent = 8;
# Queuing
# When true, Transmission will only download
@ -139,27 +209,17 @@ in
# notify me when download finished
script-torrent-done-enabled = true;
#script-torrent-done-filename =
# (pkgs.writers.writeBash "torrent-finished" ''
# JSON_STRING=$( ${pkgs.jq}/bin/jq -n --arg torrent_name "$TR_TORRENT_NAME" \
# '{text: ":tada: finished : \($torrent_name)", channel: "torrent"}' )
# ${pkgs.curl}/bin/curl \
# --include \
# --request POST \
# --data-urlencode \
# "payload=$JSON_STRING" \
# <url>
# '');
script-torrent-done-filename = completionScript;
};
};
networking.firewall = {
allowedTCPPorts = [ 51413 ];
allowedUDPPorts = [ 51413 ];
# only allow access via nginx (proxy to localhost)
interfaces.eth0 = {
allowedTCPPorts = [ 9091 ];
allowedUDPPorts = [ 9091 ];
allowedTCPPorts = [ uiPort ];
allowedUDPPorts = [ uiPort ];
};
};
@ -167,7 +227,16 @@ in
systemd.services.transmission = {
bindsTo = [ "openvpn-nordvpn.service" ];
after = [ "openvpn-nordvpn.service" ];
serviceConfig.Restart = "always";
serviceConfig = {
Restart = "always";
EnvironmentFile = [
"/run/secrets/transmissionPushover"
];
BindPaths = lib.mkForce [
"/media"
"/var/lib/transmission/.config/transmission-daemon"
];
};
};
services.openvpn.servers.nordvpn.updateResolvConf = true;
services.openvpn.servers.nordvpn.config = ''
@ -263,21 +332,23 @@ in
# give containers internet access
networking.nat.enable = true;
networking.nat.internalInterfaces = [ "ve-torrent" ];
networking.nat.externalInterface = "enp2s0f1";
networking.nat.externalInterface = hostInterface;
# open ports for logging
networking.firewall.interfaces."ve-torrent".allowedTCPPorts =
[ 5044 12304 12305 ];
networking.firewall.interfaces."ve-torrent".allowedUDPPorts =
[ 5044 12304 12305 ];
#networking.firewall.interfaces."ve-torrent".allowedTCPPorts =
# [ 5044 12304 12305 ];
#networking.firewall.interfaces."ve-torrent".allowedUDPPorts =
# [ 5044 12304 12305 ];
# host nginx setup
# curl transmission.robi.private < will work
# curl -H "Host: transmission.robi.private" http://144.76.13.147/ < won't work
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"transmission.workhorse.private" = {
locations."/" = { proxyPass = "http://${containerAddress}:9091"; };
"transmission.${config.networking.hostName}.private" = {
locations."/" = { proxyPass = "http://${containerAddress}:${toString uiPort}"; };
};
};
};