{ config, pkgs, ... }: let kittykatHost = "49.13.170.223"; sshKeyPath = "/root/.ssh/id_rsa"; overlordTunIp = "10.0.0.1"; kittykatTunIp = "10.0.0.2"; zomboidUdpPorts = [ 16261 16262 16263 16264 16265 16266 16267 16268 16269 16270 16271 16272 52015 ]; in { boot.kernelModules = ["tun"]; networking.interfaces.tun0 = { virtual = true; virtualType = "tun"; ipv4.addresses = [ { address = overlordTunIp; prefixLength = 30; } ]; }; networking.firewall = { enable = true; interfaces.tun0.allowedUDPPorts = zomboidUdpPorts; }; systemd.services.ssh-tun-kittykat = { description = "Persistent SSH TUN tunnel to kittykat"; after = [ "network-online.target" "systemd-networkd-wait-online.service" "NetworkManager-wait-online.service" "systemd-modules-load.service" "network-addresses-tun0.service" ]; wants = ["network-online.target"]; wantedBy = ["multi-user.target"]; path = [ pkgs.openssh pkgs.iproute2 pkgs.coreutils pkgs.kmod pkgs.bash ]; serviceConfig = { Type = "simple"; User = "root"; Restart = "always"; RestartSec = "5s"; StartLimitIntervalSec = 0; }; preStart = '' modprobe tun || true ip addr replace ${overlordTunIp}/30 dev tun0 || true ip link set dev tun0 up || true for i in $(seq 1 60); do if ip route get ${kittykatHost} >/dev/null 2>&1; then exit 0 fi sleep 2 done echo "No route to ${kittykatHost} after waiting." exit 1 ''; script = '' exec ssh \ -i ${sshKeyPath} \ -o BatchMode=yes \ -o StrictHostKeyChecking=accept-new \ -o ServerAliveInterval=15 \ -o ServerAliveCountMax=3 \ -o ExitOnForwardFailure=yes \ -o Tunnel=point-to-point \ -w 0:0 \ root@${kittykatHost} \ "ip addr replace ${kittykatTunIp}/30 dev tun0 && ip link set dev tun0 up && exec sleep infinity" ''; }; }