nixos/server/deluge/default.nix
2025-12-04 13:28:25 +01:00

154 lines
5.2 KiB
Nix

{
lib,
config,
pkgs,
...
}:
{
options.server.deluge.enable = lib.mkEnableOption "Enable deluge torrent client";
config = lib.mkIf config.server.deluge.enable {
services.deluge = {
enable = true;
web.enable = true;
};
environment.systemPackages = with pkgs; [ libnatpmp ];
networking.firewall.allowedTCPPorts = [ 8112 ];
# creating network namespace
systemd.services."netns@" = {
description = "%I network namespace";
before = [ "network.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.iproute2}/bin/ip netns add %I";
ExecStop = "${pkgs.iproute2}/bin/ip netns del %I";
};
};
systemd.services.wg-port-opener = {
description = "port opener for protonvpn";
bindsTo = [ "netns@wg.service" ];
requires = [ "network-online.target" ];
after = [ "netns@wg.service" ];
serviceConfig = {
Type = "exec";
NetworkNamespacePath = [ "/var/run/netns/wg" ];
ExecStart =
with pkgs;
writers.writeBash "port-opening" ''
while true; do
date;
${libnatpmp}/bin/natpmpc -a 1 0 udp 60 -g 10.2.0.1 || { echo -e "ERROR with natpmpc udp command \a" ; break ; };
${libnatpmp}/bin/natpmpc -a 1 0 tcp 60 -g 10.2.0.1 || { echo -e "ERROR with natpmpc tcp command \a" ; break ; };
sleep 45;
done;
'';
};
};
# setting up wireguard interface within network namespace
systemd.services.wg = {
description = "wg network interface";
bindsTo = [ "netns@wg.service" ];
requires = [ "network-online.target" ];
after = [ "netns@wg.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart =
with pkgs;
writers.writeBash "wg-up" ''
${iproute2}/bin/ip link add wg0 type wireguard
${iproute2}/bin/ip link set wg0 netns wg
${iproute2}/bin/ip -n wg address add 10.2.0.2/32 dev wg0
# ${iproute2}/bin/ip -n wg -6 address add fc00:bbbb:bbbb:bb01::a:1674/128 dev wg0
${iproute2}/bin/ip netns exec wg \
${wireguard-tools}/bin/wg setconf wg0 /root/proton.conf
${iproute2}/bin/ip -n wg link set wg0 up
# need to set lo up as network namespace is started with lo down
${iproute2}/bin/ip -n wg link set lo up
${iproute2}/bin/ip -n wg route add default dev wg0
${iproute2}/bin/ip -n wg -6 route add default dev wg0
'';
ExecStop =
with pkgs;
writers.writeBash "wg-down" ''
${iproute2}/bin/ip -n wg route del default dev wg0
${iproute2}/bin/ip -n wg -6 route del default dev wg0
${iproute2}/bin/ip -n wg link del wg0
'';
};
};
# binding deluged to network namespace
systemd.services.deluged.bindsTo = [ "netns@wg.service" ];
systemd.services.deluged.requires = [
"network-online.target"
"wg.service"
];
systemd.services.deluged.serviceConfig.NetworkNamespacePath = [ "/var/run/netns/wg" ];
systemd.services.deluge-port-setter = {
description = "sets deluge ports";
bindsTo = [ "netns@wg.service" ];
requires = [ "network-online.target" ];
after = [ "deluged.service" ];
serviceConfig = {
Type = "oneshot";
User = "deluge";
RemainAfterExit = true;
NetworkNamespacePath = [ "/var/run/netns/wg" ];
ExecStart =
with pkgs;
writers.writeBash "deluge-ports" ''
TCP=($(${libnatpmp}/bin/natpmpc -a 1 0 tcp 60 -g 10.2.0.1 2> /dev/null | grep Mapped))
TCP_PORT=''${TCP[3]}
UDP=($(${libnatpmp}/bin/natpmpc -a 1 0 udp 60 -g 10.2.0.1 2> /dev/null | grep Mapped))
UDP_PORT=''${UDP[3]}
echo "The ports are"
echo "TCP: $TCP_PORT"
echo "UDP: $UDP_PORT"
PORTS="($TCP_PORT, $UDP_PORT)"
${deluge}/bin/deluge-console "config -s random_port false; config -s listen_ports $PORTS"
exit 0
'';
};
};
# allowing delugeweb to access deluged in network namespace, a socket is necesarry
systemd.sockets."proxy-to-deluged" = {
enable = true;
description = "Socket for Proxy to Deluge Daemon";
listenStreams = [ "58846" ];
wantedBy = [ "sockets.target" ];
};
# creating proxy service on socket, which forwards the same port from the root namespace to the isolated namespace
systemd.services."proxy-to-deluged" = {
enable = true;
description = "Proxy to Deluge Daemon in Network Namespace";
requires = [
"deluged.service"
"proxy-to-deluged.socket"
];
after = [
"deluged.service"
"proxy-to-deluged.socket"
];
unitConfig = {
JoinsNamespaceOf = "deluged.service";
};
serviceConfig = {
User = "deluge";
Group = "deluge";
ExecStart = "${pkgs.systemd}/lib/systemd/systemd-socket-proxyd --exit-idle-time=5min 127.0.0.1:58846";
PrivateNetwork = "yes";
};
};
};
}