Removed vpn, using Maroka's instead, removes all containerization :')
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.nixarr.ddns;
|
||||
in {
|
||||
options.nixarr.ddns = {
|
||||
njalla = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
**Required options:**
|
||||
|
||||
- [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile)
|
||||
|
||||
Whether or not to enable DDNS for a [Njalla](https://njal.la/)
|
||||
domain.
|
||||
'';
|
||||
};
|
||||
|
||||
keysFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
A path to a JSON-file containing key value pairs of domains and keys.
|
||||
|
||||
To get the keys, create a dynamic njalla record. Upon creation
|
||||
you should see something like the following command suggested:
|
||||
|
||||
```sh
|
||||
curl "https://njal.la/update/?h=jellyfin.example.com&k=zeubesojOLgC2eJC&auto"
|
||||
```
|
||||
|
||||
Then the JSON-file you pass here should contain:
|
||||
|
||||
```json
|
||||
{
|
||||
"jellyfin.example.com": "zeubesojOLgC2eJC"
|
||||
}
|
||||
```
|
||||
|
||||
You can, of course, add more key-value pairs than just one.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.njalla.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.njalla.enable -> cfg.njalla.keysFile != null;
|
||||
message = ''
|
||||
The nixarr.ddns.njalla.enable option requires the
|
||||
nixarr.ddns.njalla.keysFile option to be set, but it was not.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
systemd.timers = mkIf cfg.njalla.enable {
|
||||
ddnsNjalla = {
|
||||
description = "Timer for setting the Njalla DDNS records";
|
||||
|
||||
timerConfig = {
|
||||
OnBootSec = "30"; # Run 30 seconds after system boot
|
||||
OnCalendar = "hourly";
|
||||
Persistent = true; # Run service immediately if last window was missed
|
||||
RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
|
||||
};
|
||||
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = let
|
||||
ddns-njalla = pkgs.writeShellApplication {
|
||||
name = "ddns-njalla";
|
||||
|
||||
runtimeInputs = with pkgs; [ curl jq ];
|
||||
|
||||
# Thanks chatgpt...
|
||||
text = ''
|
||||
# Path to the JSON file
|
||||
json_file="${cfg.njalla.keysFile}"
|
||||
|
||||
# Convert the JSON object into a series of tab-separated key-value pairs using jq
|
||||
# - `to_entries[]`: Convert the object into an array of key-value pairs.
|
||||
# - `[.key, .value]`: For each pair, create an array containing the key and the value.
|
||||
# - `@tsv`: Convert the array to a tab-separated string.
|
||||
# The output will be a series of lines, each containing a key and a value separated by a tab.
|
||||
jq_command='to_entries[] | [.key, .value] | @tsv'
|
||||
|
||||
# Read the converted output line by line
|
||||
# - `IFS=$'\t'`: Use the tab character as the field separator.
|
||||
# - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator.
|
||||
while IFS=$'\t' read -r key val; do
|
||||
# For each key-value pair, execute the curl command
|
||||
# Replace `''${key}` and `''${val}` in the URL with the actual key and value.
|
||||
curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto"
|
||||
done < <(jq -r "$jq_command" "$json_file")
|
||||
'';
|
||||
};
|
||||
in mkIf cfg.njalla.enable {
|
||||
ddnsNjalla = {
|
||||
description = "Sets the Njalla DDNS records";
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = getExe ddns-njalla;
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
+69
-164
@@ -1,4 +1,4 @@
|
||||
{
|
||||
vpnconfinement: {
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
@@ -8,7 +8,9 @@ with lib; let
|
||||
cfg = config.nixarr;
|
||||
in {
|
||||
imports = [
|
||||
vpnconfinement.nixosModules.default
|
||||
./jellyfin
|
||||
./ddns
|
||||
./radarr
|
||||
./lidarr
|
||||
./readarr
|
||||
@@ -70,46 +72,6 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
ddns.njalla = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
**Required options:**
|
||||
|
||||
- [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile)
|
||||
|
||||
Whether or not to enable DDNS for a [Njalla](https://njal.la/)
|
||||
domain.
|
||||
'';
|
||||
};
|
||||
|
||||
keysFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
A path to a JSON-file containing key value pairs of domains and keys.
|
||||
|
||||
To get the keys, create a dynamic njalla record. Upon creation
|
||||
you should see something like the following command suggested:
|
||||
|
||||
```sh
|
||||
curl "https://njal.la/update/?h=jellyfin.example.com&k=zeubesojOLgC2eJC&auto"
|
||||
```
|
||||
|
||||
Then the JSON-file you pass here should contain:
|
||||
|
||||
```json
|
||||
{
|
||||
"jellyfin.example.com": "zeubesojOLgC2eJC"
|
||||
}
|
||||
```
|
||||
|
||||
You can, of course, add more key-value pairs than just one.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
vpn = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
@@ -128,16 +90,6 @@ in {
|
||||
description = "The path to the wireguard configuration file.";
|
||||
};
|
||||
|
||||
dnsServers = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
default = null;
|
||||
description = ''
|
||||
Extra DNS servers for the VPN. If your wg config has a DNS field,
|
||||
then this should not be necessary.
|
||||
'';
|
||||
example = ["1.1.1.2"];
|
||||
};
|
||||
|
||||
vpnTestService = {
|
||||
enable = mkEnableOption ''
|
||||
the vpn test service. Useful for testing DNS leaks or if the VPN
|
||||
@@ -145,10 +97,11 @@ in {
|
||||
'';
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 12300;
|
||||
type = with types; nullOr port;
|
||||
default = null;
|
||||
description = ''
|
||||
The port that the vpn test service listens to.
|
||||
The port that netcat listens to on the vpn test service. If set to
|
||||
`null`, then netcat will not be started.
|
||||
'';
|
||||
example = 58403;
|
||||
};
|
||||
@@ -157,7 +110,7 @@ in {
|
||||
openTcpPorts = mkOption {
|
||||
type = with types; listOf port;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
description = ''
|
||||
What TCP ports to allow traffic from. You might need this if you're
|
||||
port forwarding on your VPN provider and you're setting up services
|
||||
not covered in by this module that uses the VPN.
|
||||
@@ -168,7 +121,7 @@ in {
|
||||
openUdpPorts = mkOption {
|
||||
type = with types; listOf port;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
description = ''
|
||||
What UDP ports to allow traffic from. You might need this if you're
|
||||
port forwarding on your VPN provider and you're setting up services
|
||||
not covered in by this module that uses the VPN.
|
||||
@@ -187,149 +140,101 @@ in {
|
||||
to be set, but it was not.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.ddns.njalla.enable -> cfg.ddns.njalla.keysFile != null;
|
||||
message = ''
|
||||
The nixarr.ddns.njalla.enable option requires the
|
||||
nixarr.ddns.njalla.keysFile option to be set, but it was not.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
# TODO: move this to modules, at least the "*Arrs"...
|
||||
users.groups = {
|
||||
media.gid = 992;
|
||||
prowlarr = {};
|
||||
media = {};
|
||||
streamer = {};
|
||||
torrenter = {};
|
||||
};
|
||||
# TODO: This is BAD. But seems necessary when using containers.
|
||||
# The prefered solution is to just remove containerization.
|
||||
# Look at https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/misc/ids.nix
|
||||
# See also issue: https://github.com/rasmus-kirk/nixarr/issues/1
|
||||
users.users = {
|
||||
streamer = {
|
||||
isSystemUser = true;
|
||||
group = "streamer";
|
||||
uid = lib.mkForce 316;
|
||||
};
|
||||
sonarr = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
uid = lib.mkForce 274;
|
||||
};
|
||||
radarr = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
uid = lib.mkForce 275;
|
||||
};
|
||||
lidarr = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
uid = lib.mkForce 306;
|
||||
};
|
||||
readarr = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
uid = lib.mkForce 309;
|
||||
};
|
||||
torrenter = {
|
||||
isSystemUser = true;
|
||||
group = "torrenter";
|
||||
uid = lib.mkForce 70;
|
||||
};
|
||||
prowlarr = {
|
||||
isSystemUser = true;
|
||||
group = "prowlarr";
|
||||
uid = lib.mkForce 293;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
# Media dirs
|
||||
"d '${cfg.mediaDir}' 0775 root media - -"
|
||||
"d '${cfg.mediaDir}/library' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/shows' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/movies' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/music' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/books' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/torrents' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/.incomplete' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/.watch' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/manual' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/liadarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/radarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/sonarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/readarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}' 0775 root media - -"
|
||||
"d '${cfg.mediaDir}/library' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/shows' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/movies' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/music' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/library/books' 0775 streamer media - -"
|
||||
"d '${cfg.mediaDir}/torrents' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/.incomplete' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/.watch' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/manual' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/liadarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/radarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/sonarr' 0755 torrenter media - -"
|
||||
"d '${cfg.mediaDir}/torrents/readarr' 0755 torrenter media - -"
|
||||
];
|
||||
|
||||
util-nixarr.vpnnamespace = {
|
||||
enable = cfg.vpn.enable;
|
||||
# TODO: wtf to do about openports
|
||||
vpnnamespaces.wg = {
|
||||
enable = cfg.vpn.enable ;
|
||||
accessibleFrom = [
|
||||
"192.168.1.0/24"
|
||||
"127.0.0.1"
|
||||
];
|
||||
dnsServers = cfg.vpn.dnsServers;
|
||||
wireguardAddressPath = cfg.vpn.wgAddress;
|
||||
wireguardConfigFile = if cfg.vpn.wgConf != null then cfg.vpn.wgConf else "";
|
||||
vpnTestService = {
|
||||
enable = cfg.vpn.vpnTestService.enable;
|
||||
port = cfg.vpn.vpnTestService.port;
|
||||
};
|
||||
openTcpPorts = cfg.vpn.openTcpPorts;
|
||||
openUdpPorts = cfg.vpn.openUdpPorts;
|
||||
wireguardConfigFile = cfg.vpn.wgConf;
|
||||
};
|
||||
|
||||
systemd.timers = mkIf cfg.ddns.njalla.enable {
|
||||
ddnsNjalla = {
|
||||
description = "Timer for setting the Njalla DDNS records";
|
||||
|
||||
timerConfig = {
|
||||
OnBootSec = "30"; # Run 30 seconds after system boot
|
||||
OnCalendar = "hourly";
|
||||
Persistent = true; # Run service immediately if last window was missed
|
||||
RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
|
||||
};
|
||||
|
||||
wantedBy = ["multi-user.target"];
|
||||
# TODO: openports
|
||||
systemd.services.vpn-test-service = {
|
||||
enable = cfg.vpn.vpnTestService.enable;
|
||||
vpnconfinement = {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = let
|
||||
ddns-njalla = pkgs.writeShellApplication {
|
||||
name = "ddns-njalla";
|
||||
script = let
|
||||
vpn-test = pkgs.writeShellApplication {
|
||||
name = "vpn-test";
|
||||
|
||||
runtimeInputs = with pkgs; [ curl jq ];
|
||||
runtimeInputs = with pkgs; [util-linux unixtools.ping coreutils curl bash libressl netcat-gnu openresolv dig];
|
||||
|
||||
# Thanks chatgpt...
|
||||
text = ''
|
||||
# Path to the JSON file
|
||||
json_file="${cfg.ddns.njalla.keysFile}"
|
||||
text = ''
|
||||
cd "$(mktemp -d)"
|
||||
|
||||
# Convert the JSON object into a series of tab-separated key-value pairs using jq
|
||||
# - `to_entries[]`: Convert the object into an array of key-value pairs.
|
||||
# - `[.key, .value]`: For each pair, create an array containing the key and the value.
|
||||
# - `@tsv`: Convert the array to a tab-separated string.
|
||||
# The output will be a series of lines, each containing a key and a value separated by a tab.
|
||||
jq_command='to_entries[] | [.key, .value] | @tsv'
|
||||
# Print resolv.conf
|
||||
echo "/etc/resolv.conf contains:"
|
||||
cat /etc/resolv.conf
|
||||
|
||||
# Read the converted output line by line
|
||||
# - `IFS=$'\t'`: Use the tab character as the field separator.
|
||||
# - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator.
|
||||
while IFS=$'\t' read -r key val; do
|
||||
# For each key-value pair, execute the curl command
|
||||
# Replace `''${key}` and `''${val}` in the URL with the actual key and value.
|
||||
curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto"
|
||||
done < <(jq -r "$jq_command" "$json_file")
|
||||
'';
|
||||
};
|
||||
in mkIf cfg.ddns.njalla.enable {
|
||||
ddnsNjalla = {
|
||||
description = "Sets the Njalla DDNS records";
|
||||
# Query resolvconf
|
||||
echo "resolvconf output:"
|
||||
resolvconf -l
|
||||
echo ""
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = getExe ddns-njalla;
|
||||
Type = "oneshot";
|
||||
# Get ip
|
||||
echo "Getting IP:"
|
||||
curl -s ipinfo.io
|
||||
|
||||
echo -ne "DNS leak test:"
|
||||
curl -s https://raw.githubusercontent.com/macvk/dnsleaktest/b03ab54d574adbe322ca48cbcb0523be720ad38d/dnsleaktest.sh -o dnsleaktest.sh
|
||||
chmod +x dnsleaktest.sh
|
||||
./dnsleaktest.sh
|
||||
'' + (if cfg.vpn.vpnTestService.port != null then ''
|
||||
echo "starting netcat on port ${builtins.toString cfg.vpn.vpnTestService.port}:"
|
||||
nc -vnlp ${builtins.toString cfg.vpn.vpnTestService.port}
|
||||
'' else "");
|
||||
};
|
||||
in "${vpn-test}/bin/vpn-test";
|
||||
|
||||
bindsTo = ["netns@wg.service"];
|
||||
requires = ["network-online.target"];
|
||||
after = ["wg.service"];
|
||||
serviceConfig = {
|
||||
#User = "torrenter";
|
||||
NetworkNamespacePath = "/var/run/netns/wg";
|
||||
BindReadOnlyPaths = ["/etc/netns/wg/resolv.conf:/etc/resolv.conf:norbind" "/data/test.file:/etc/test.file:norbind"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ let
|
||||
cfg = config.nixarr.jellyfin;
|
||||
defaultPort = 8096;
|
||||
nixarr = config.nixarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
in with lib; {
|
||||
options.nixarr.jellyfin = {
|
||||
enable = mkEnableOption "the Jellyfin service.";
|
||||
@@ -228,57 +227,16 @@ in with lib; {
|
||||
defaults.email = cfg.expose.https.acmeMail;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(
|
||||
mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services."container@jellyfin" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.jellyfin.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.jellyfin = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}/library".isReadOnly = false;
|
||||
"${cfg.stateDir}".isReadOnly = false;
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.streamer = {
|
||||
gid = config.users.groups.streamer.gid;
|
||||
};
|
||||
users.users.streamer = {
|
||||
uid = lib.mkForce config.users.users.streamer.uid;
|
||||
isSystemUser = true;
|
||||
group = "streamer";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
user = "streamer";
|
||||
group = "streamer";
|
||||
logDir = "${cfg.stateDir}/log";
|
||||
cacheDir = "${cfg.stateDir}/cache";
|
||||
dataDir = "${cfg.stateDir}/data";
|
||||
configDir = "${cfg.stateDir}/config";
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
# TODO: openports if expose.vpn
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.nixarr.lidarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
nixarr = config.nixarr;
|
||||
in {
|
||||
options.nixarr.lidarr = {
|
||||
@@ -50,53 +49,16 @@ in {
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(
|
||||
mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services."container@lidarr" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.lidarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.lidarr = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}".isReadOnly = false;
|
||||
"${cfg.stateDir}".isReadOnly = false;
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.media = {
|
||||
gid = config.users.groups.media.gid;
|
||||
};
|
||||
users.users.lidarr = {
|
||||
uid = lib.mkForce config.users.users.lidarr.uid;
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
services.lidarr = {
|
||||
enable = true;
|
||||
group = "media";
|
||||
dataDir = "${cfg.stateDir}";
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
# TODO: openports
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
@@ -75,19 +75,16 @@ in {
|
||||
''
|
||||
] else [];
|
||||
|
||||
util-nixarr.vpnnamespace = {
|
||||
portMappings = builtins.map (x: { From = x; To = x; }) config.services.openssh.ports;
|
||||
openUdpPorts = config.services.openssh.ports;
|
||||
openTcpPorts = config.services.openssh.ports;
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.openssh.vpnconfinement = {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
systemd.services.openssh = {
|
||||
bindsTo = [ "netns@wg.service" ];
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "wg.service" ];
|
||||
serviceConfig = {
|
||||
NetworkNamespacePath = "/var/run/netns/wg";
|
||||
};
|
||||
# Port mappings
|
||||
# TODO: openports
|
||||
vpnnamespaces.wg = {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+10
-40
@@ -6,7 +6,6 @@
|
||||
}:
|
||||
with lib; let
|
||||
defaultPort = 9696;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
nixarr = config.nixarr;
|
||||
cfg = config.nixarr.prowlarr;
|
||||
in {
|
||||
@@ -49,51 +48,22 @@ in {
|
||||
"d '${cfg.stateDir}' 0700 prowlarr root - -"
|
||||
];
|
||||
|
||||
util-nixarr.services.prowlarr = mkIf (!cfg.vpn.enable) {
|
||||
users.groups.prowlarr = {};
|
||||
|
||||
util-nixarr.services.prowlarr = {
|
||||
enable = true;
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(
|
||||
mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services."container@prowlarr" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.prowlarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.prowlarr = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
bindMounts."${cfg.stateDir}".isReadOnly = false;
|
||||
|
||||
config = {
|
||||
users.groups.prowlarr = {};
|
||||
users.users.prowlarr = {
|
||||
uid = lib.mkForce config.users.users.prowlarr.uid;
|
||||
isSystemUser = true;
|
||||
group = "prowlarr";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
util-nixarr.services.prowlarr = {
|
||||
enable = true;
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
@@ -8,7 +8,6 @@ with lib; let
|
||||
cfg = config.nixarr.radarr;
|
||||
defaultPort = 7878;
|
||||
nixarr = config.nixarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
in {
|
||||
options.nixarr.radarr = {
|
||||
enable = mkEnableOption "Enable the Radarr service.";
|
||||
@@ -45,60 +44,22 @@ in {
|
||||
"d '${cfg.stateDir}' 0700 radarr root - -"
|
||||
];
|
||||
|
||||
services.radarr = mkIf (!cfg.vpn.enable) {
|
||||
services.radarr = {
|
||||
enable = cfg.enable;
|
||||
user = "radarr";
|
||||
group = "media";
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(
|
||||
mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services."container@radarr" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.radarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.radarr = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}".isReadOnly = false;
|
||||
"${cfg.stateDir}".isReadOnly = false;
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.media = {
|
||||
gid = config.users.groups.media.gid;
|
||||
};
|
||||
users.users.radarr = {
|
||||
uid = lib.mkForce config.users.users.radarr.uid;
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
services.radarr = {
|
||||
enable = true;
|
||||
group = "media";
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
with lib; let
|
||||
cfg = config.nixarr.readarr;
|
||||
nixarr = config.nixarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
in {
|
||||
options.nixarr.readarr = {
|
||||
enable = mkEnableOption "Enable the Readarr service";
|
||||
@@ -50,53 +49,15 @@ in {
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(
|
||||
mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services."container@readarr" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.readarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.readarr = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}".isReadOnly = false;
|
||||
"${cfg.stateDir}".isReadOnly = false;
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.media = {
|
||||
gid = config.users.groups.media.gid;
|
||||
};
|
||||
users.users.readarr = {
|
||||
uid = lib.mkForce config.users.users.readarr.uid;
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
services.readarr = {
|
||||
enable = true;
|
||||
group = "media";
|
||||
dataDir = "${cfg.stateDir}";
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
@@ -8,7 +8,6 @@ with lib; let
|
||||
cfg = config.nixarr.sonarr;
|
||||
defaultPort = 8989;
|
||||
nixarr = config.nixarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
in {
|
||||
options.nixarr.sonarr = {
|
||||
enable = mkOption {
|
||||
@@ -49,60 +48,22 @@ in {
|
||||
"d '${cfg.stateDir}' 0700 sonarr root - -"
|
||||
];
|
||||
|
||||
services.sonarr = mkIf (!cfg.vpn.enable) {
|
||||
services.sonarr = {
|
||||
enable = cfg.enable;
|
||||
user = "sonarr";
|
||||
group = "media";
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace.portMappings = [
|
||||
(mkIf cfg.vpn.enable {
|
||||
From = defaultPort;
|
||||
To = defaultPort;
|
||||
})
|
||||
];
|
||||
|
||||
systemd.services."container@sonarr" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.sonarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
containers.sonarr = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}".isReadOnly = false;
|
||||
"${cfg.stateDir}".isReadOnly = false;
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.media = {
|
||||
gid = config.users.groups.media.gid;
|
||||
};
|
||||
users.users.sonarr = {
|
||||
uid = lib.mkForce config.users.users.sonarr.uid;
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
users.groups.media = {};
|
||||
|
||||
services.sonarr = {
|
||||
enable = cfg.enable;
|
||||
group = "media";
|
||||
dataDir = cfg.stateDir;
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
@@ -80,6 +80,7 @@ in {
|
||||
|
||||
users.users = mkIf (cfg.user == "cross-seed") {
|
||||
cross-seed = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
+18
-115
@@ -7,7 +7,6 @@
|
||||
with lib; let
|
||||
cfg = config.nixarr.transmission;
|
||||
nixarr = config.nixarr;
|
||||
dnsServers = config.lib.vpn.dnsServers;
|
||||
cfg-cross-seed = config.nixarr.transmission.privateTrackers.cross-seed;
|
||||
transmissionCrossSeedScript = with builtins; pkgs.writeShellApplication {
|
||||
name = "mk-cross-seed-credentials";
|
||||
@@ -198,7 +197,7 @@ in {
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${cfg.stateDir}' 0700 torrenter root - -"
|
||||
"d '${cfg.stateDir}' 0700 torrenter root - -"
|
||||
# This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883)
|
||||
"d '${cfg.stateDir}/.config/transmission-daemon' 0700 torrenter root - -"
|
||||
] ++ (
|
||||
@@ -230,7 +229,7 @@ in {
|
||||
)];
|
||||
};
|
||||
|
||||
services.transmission = mkIf (!cfg.vpn.enable) {
|
||||
services.transmission = {
|
||||
enable = true;
|
||||
user = "torrenter";
|
||||
group = "torrenter";
|
||||
@@ -250,10 +249,11 @@ in {
|
||||
watch-dir-enabled = true;
|
||||
watch-dir = "${nixarr.mediaDir}/torrents/.watch";
|
||||
|
||||
rpc-bind-address = "127.0.0.1";
|
||||
rpc-bind-address = if cfg.vpn.enable then "192.168.15.1" else "127.0.0.1";
|
||||
rpc-port = cfg.uiPort;
|
||||
rpc-whitelist-enabled = true;
|
||||
rpc-whitelist = "192.168.15.1,127.0.0.1";
|
||||
# TODO: fix this for ssh tunneling...
|
||||
rpc-whitelist-enabled = false;
|
||||
rpc-whitelist = "192.168.15.1,127.0.0.1,192.168.1.*,192.168.0.*";
|
||||
rpc-authentication-required = false;
|
||||
|
||||
blocklist-enabled = true;
|
||||
@@ -269,8 +269,8 @@ in {
|
||||
anti-brute-force-enabled = true;
|
||||
anti-brute-force-threshold = 10;
|
||||
|
||||
script-torrent-done-enabled = true;
|
||||
script-torrent-done-filename = getExe transmissionCrossSeedScript;
|
||||
script-torrent-done-enabled = cfg-cross-seed.enable;
|
||||
script-torrent-done-filename = if cfg-cross-seed.enable then transmissionCrossSeedScript else null;
|
||||
|
||||
message-level =
|
||||
if cfg.messageLevel == "none"
|
||||
@@ -292,115 +292,18 @@ in {
|
||||
// cfg.extraSettings;
|
||||
};
|
||||
|
||||
util-nixarr.vpnnamespace = mkIf cfg.vpn.enable {
|
||||
portMappings = [
|
||||
{
|
||||
From = cfg.uiPort;
|
||||
To = cfg.uiPort;
|
||||
}
|
||||
];
|
||||
openUdpPorts = [cfg.peerPort];
|
||||
openTcpPorts = [cfg.peerPort];
|
||||
# Enable and specify VPN namespace to confine service in.
|
||||
systemd.services.transmission.vpnconfinement = mkIf cfg.vpn.enable {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
|
||||
systemd.services."container@transmission" = mkIf cfg.vpn.enable {
|
||||
requires = ["wg.service"];
|
||||
};
|
||||
|
||||
containers.transmission = mkIf cfg.vpn.enable {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
extraFlags = ["--network-namespace-path=/var/run/netns/wg"];
|
||||
|
||||
bindMounts = {
|
||||
"${nixarr.mediaDir}/torrents".isReadOnly = false;
|
||||
"/var/lib/transmission" = {
|
||||
hostPath = cfg.stateDir;
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
users.groups.torrenter = {
|
||||
gid = config.users.groups.torrenter.gid;
|
||||
};
|
||||
users.users.torrenter = {
|
||||
uid = lib.mkForce config.users.users.torrenter.uid;
|
||||
isSystemUser = true;
|
||||
group = "torrenter";
|
||||
};
|
||||
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
services.resolved.enable = true;
|
||||
networking.nameservers = dnsServers;
|
||||
|
||||
systemd.services.transmission.serviceConfig = {
|
||||
RootDirectoryStartOnly = lib.mkForce false;
|
||||
RootDirectory = lib.mkForce "";
|
||||
};
|
||||
|
||||
services.transmission = {
|
||||
enable = true;
|
||||
user = "torrenter";
|
||||
group = "torrenter";
|
||||
webHome =
|
||||
if cfg.flood.enable
|
||||
then pkgs.flood-for-transmission
|
||||
else null;
|
||||
package = pkgs.transmission_4;
|
||||
openRPCPort = true;
|
||||
openPeerPorts = true;
|
||||
settings =
|
||||
{
|
||||
download-dir = "${nixarr.mediaDir}/torrents";
|
||||
incomplete-dir-enabled = true;
|
||||
incomplete-dir = "${nixarr.mediaDir}/torrents/.incomplete";
|
||||
watch-dir-enabled = true;
|
||||
watch-dir = "${nixarr.mediaDir}/torrents/.watch";
|
||||
|
||||
rpc-bind-address = "192.168.15.1";
|
||||
rpc-port = cfg.uiPort;
|
||||
rpc-whitelist-enabled = false;
|
||||
rpc-whitelist = "192.168.15.1,127.0.0.1";
|
||||
rpc-authentication-required = false;
|
||||
|
||||
blocklist-enabled = true;
|
||||
blocklist-url = "https://github.com/Naunter/BT_BlockLists/raw/master/bt_blocklists.gz";
|
||||
|
||||
peer-port = cfg.peerPort;
|
||||
dht-enabled = !cfg.privateTrackers.disableDhtPex;
|
||||
pex-enabled = !cfg.privateTrackers.disableDhtPex;
|
||||
utp-enabled = false;
|
||||
encryption = 1;
|
||||
port-forwarding-enabled = false;
|
||||
|
||||
anti-brute-force-enabled = true;
|
||||
anti-brute-force-threshold = 10;
|
||||
|
||||
# 0 = None, 1 = Critical, 2 = Error, 3 = Warn, 4 = Info, 5 = Debug, 6 = Trace
|
||||
message-level = 3;
|
||||
}
|
||||
// cfg.extraSettings;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
wget
|
||||
util-linux
|
||||
unixtools.ping
|
||||
coreutils
|
||||
curl
|
||||
bash
|
||||
libressl
|
||||
netcat-gnu
|
||||
openresolv
|
||||
dig
|
||||
];
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
# Port mappings
|
||||
# TODO: open peerPort
|
||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||
portMappings = [{ From = cfg.uiPort; To = cfg.uiPort; }];
|
||||
#openUdpPorts = [cfg.peerPort];
|
||||
#openTcpPorts = [cfg.peerPort];
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfg.vpn.enable {
|
||||
|
||||
Reference in New Issue
Block a user