nixdots/modules/servers/per-host/kittykat/tunnel.nix
2026-05-11 18:19:58 +03:00

107 lines
2.6 KiB
Nix

{
config,
pkgs,
...
}: let
# kittykat public NIC
publicInterface = "enp1s0";
# SSH tunnel IPs
overlordTunIp = "10.0.0.1";
kittykatTunIp = "10.0.0.2";
# Zomboid ports:
# 16261 = main game port
# 16262+ = player ports, using 16262-16272 as a sane test range
# 52015 = extra UDP port your server is listening on
zomboidUdpPorts = [
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
52015
];
in {
boot.kernelModules = ["tun"];
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1;
};
services.openssh = {
enable = true;
settings = {
PermitTunnel = "yes";
# Strongly prefer key-only root login if you're using root for the tunnel.
PasswordAuthentication = false;
};
};
# Declaratively create kittykat's tun0.
networking.interfaces.tun0 = {
virtual = true;
virtualType = "tun";
ipv4.addresses = [
{
address = kittykatTunIp;
prefixLength = 30;
}
];
};
networking.firewall = {
enable = true;
# Public Zomboid UDP ports on kittykat.
allowedUDPPorts = zomboidUdpPorts;
# Allow tunnel-side packets too.
interfaces.tun0.allowedUDPPorts = zomboidUdpPorts;
};
networking.nftables = {
enable = true;
ruleset = ''
table ip zomboid_tunnel {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# Public players -> kittykat public IP -> overlord over tun0
iifname "${publicInterface}" udp dport 16261-16272 dnat to ${overlordTunIp}
iifname "${publicInterface}" udp dport 52015 dnat to ${overlordTunIp}:52015
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# Important:
# Make overlord see traffic as coming from kittykat's tun IP,
# so replies go back through the tunnel instead of overlord's normal internet route.
oifname "tun0" ip daddr ${overlordTunIp} udp dport 16261-16272 snat to ${kittykatTunIp}
oifname "tun0" ip daddr ${overlordTunIp} udp dport 52015 snat to ${kittykatTunIp}
}
chain forward {
type filter hook forward priority filter; policy accept;
# Public -> tunnel
iifname "${publicInterface}" oifname "tun0" ip daddr ${overlordTunIp} udp dport 16261-16272 accept
iifname "${publicInterface}" oifname "tun0" ip daddr ${overlordTunIp} udp dport 52015 accept
# Tunnel replies -> public
iifname "tun0" oifname "${publicInterface}" ip saddr ${overlordTunIp} accept
}
}
'';
};
}