103 lines
2.8 KiB
Nix
103 lines
2.8 KiB
Nix
{
|
|
lib,
|
|
config,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.networking.vpn-netns;
|
|
|
|
inherit (cfg.portForwarding) leaseDuration updateDuration endpoint;
|
|
|
|
forwardedServices = lib.filterAttrs (
|
|
_: value: value.enable && value.portForwarding.enable
|
|
) cfg.encapsulatedServices;
|
|
|
|
assignCount =
|
|
{ acc, temporaryPort }:
|
|
name: value: {
|
|
acc = acc ++ [
|
|
{
|
|
inherit name temporaryPort;
|
|
inherit (value.portForwarding) updateScript;
|
|
}
|
|
];
|
|
temporaryPort = temporaryPort + 1;
|
|
};
|
|
|
|
forwardedServicesWithTmpPort = lib.foldlAttrs assignCount {
|
|
acc = [ ];
|
|
temporaryPort = cfg.portForwarding.temporaryPortRange.from;
|
|
} forwardedServices;
|
|
|
|
serviceList = lib.mapAttrsToList (name: _: name + ".service") forwardedServices;
|
|
in
|
|
lib.mkIf (forwardedServices != { } && cfg.portForwarding.enable) {
|
|
assertions = [
|
|
{
|
|
assertion =
|
|
forwardedServicesWithTmpPort.temporaryPort <= cfg.portForwarding.temporaryPortRange.to + 1;
|
|
message = ''
|
|
vpn forwarding: not enough temporary ports.
|
|
Increase the range of vpn.endpoint.temporaryPortRange.
|
|
'';
|
|
}
|
|
];
|
|
|
|
systemd = {
|
|
services.natpmpc-lease = {
|
|
description = "Request VPN port forwarding leases.";
|
|
|
|
wantedBy = serviceList;
|
|
after = [ "wireguard.target" ];
|
|
wants = [ "wireguard.target" ];
|
|
|
|
# preStart = "sleep 3";
|
|
|
|
path = with pkgs; [
|
|
libnatpmp
|
|
iptables
|
|
];
|
|
|
|
script = lib.concatMapStrings (
|
|
{
|
|
temporaryPort,
|
|
name,
|
|
updateScript,
|
|
}:
|
|
let
|
|
temporaryPort' = toString temporaryPort;
|
|
leaseDuration' = toString leaseDuration;
|
|
in
|
|
''
|
|
natpmpc -g ${endpoint} -a 1 ${temporaryPort'} udp ${leaseDuration'} > /dev/null
|
|
PORT=$(natpmpc -g ${endpoint} -a 1 ${temporaryPort'} tcp ${leaseDuration'} |
|
|
grep -oP "Mapped public port \K\d+")
|
|
|
|
iptables -t nat -C PREROUTING -p udp --dport ${temporaryPort'} -j REDIRECT --to-port "$PORT" 2>/dev/null || (
|
|
iptables -t nat -A PREROUTING -p tcp --dport ${temporaryPort'} -j REDIRECT --to-port "$PORT";
|
|
iptables -t nat -A PREROUTING -p udp --dport ${temporaryPort'} -j REDIRECT --to-port "$PORT"
|
|
)
|
|
|
|
echo "Changing settings for service ${name} with port $PORT, if needed"
|
|
${updateScript}
|
|
''
|
|
) forwardedServicesWithTmpPort.acc;
|
|
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
TimeoutStartSec = 60; # toString (2 * updateDuration);
|
|
NetworkNamespacePath = "/var/run/netns/${cfg.interfaceNamespace}";
|
|
};
|
|
};
|
|
|
|
timers.natpmpc-lease = {
|
|
wantedBy = [ "timers.target" ];
|
|
timerConfig = {
|
|
OnUnitActiveSec = toString (leaseDuration - updateDuration);
|
|
Persistent = "yes";
|
|
};
|
|
};
|
|
};
|
|
}
|