From bcacdc6609d51d49aed0f698a3e5df5f4bfc7710 Mon Sep 17 00:00:00 2001 From: Jakob Lechner Date: Thu, 24 Jul 2025 03:44:00 +0200 Subject: [PATCH] Use tunnel as gateway for VoIP traffic --- hosts/pbx/networking.nix | 2 +- hosts/pbx/services/public-ip4-tunnel.nix | 72 +++++++++++++++++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/hosts/pbx/networking.nix b/hosts/pbx/networking.nix index 31d9731..e46f25f 100644 --- a/hosts/pbx/networking.nix +++ b/hosts/pbx/networking.nix @@ -9,7 +9,7 @@ useDHCP = false; # Fix Intel NIC e1000e hardware unit hang - localCommands = "${pkgs.ethtool}/bin/ethtool -K enp0s25 tso off gso off"; + localCommands = lib.mkBefore "${pkgs.ethtool}/bin/ethtool -K enp0s25 tso off gso off"; firewall.interfaces = { weinturm.allowedUDPPorts = [53 67]; diff --git a/hosts/pbx/services/public-ip4-tunnel.nix b/hosts/pbx/services/public-ip4-tunnel.nix index ffef316..1246da8 100644 --- a/hosts/pbx/services/public-ip4-tunnel.nix +++ b/hosts/pbx/services/public-ip4-tunnel.nix @@ -1,5 +1,6 @@ { config, + lib, pkgs, ... }: let @@ -17,6 +18,16 @@ in { sopsFile = ../secrets.yaml; }; + services.yate.config.ysipchan = { + general.localaddress = externalIp; + "listener external" = { + enable = "true"; + type = "udp"; + addr = externalIp; + port = 5060; + }; + }; + networking = { iproute2 = { enable = true; @@ -24,18 +35,61 @@ in { ${toString rtTable.id} ${rtTable.name} ''; }; - wireguard.interfaces."${interface}" = { + + wireguard.interfaces."${interface}" = let + rules = [ + "from 192.168.98.0/24 to 10.0.0.0/8 table main priority 10" + "from 192.168.98.0/24 to 192.168.0.0/16 table main priority 10" + "fwmark 0x1 to 192.168.0.0/16 table main priority 10" + "fwmark 0x1 to 10.0.0.0/8 table main priority 10" + + "from ${externalIp} to 10.0.0.0/8 table main priority 10" + "from ${externalIp} to 192.168.0.0/16 table main priority 10" + "from ${externalIp} table ${rtTable.name} priority 20" + "from 192.168.98.0/24 table ${interface} priority 20" + + "fwmark 0x1 table ${interface} priority 20" + ]; + addRule = rule: "ip rule add " + rule; + deleteRule = rule: "ip rule delete " + rule; + path = pkgs.lib.makeBinPath [pkgs.iproute2 pkgs.nftables]; + in { ips = ["${externalIp}/32"]; privateKeyFile = config.sops.secrets."wireguard/${interface}".path; table = rtTable.name; - postSetup = '' - ${pkgs.iproute2}/bin/ip rule add from ${externalIp} to 192.168.0.0/16 table main priority 10 - ${pkgs.iproute2}/bin/ip rule add from ${externalIp} table ${rtTable.name} priority 20 - ''; - postShutdown = '' - ${pkgs.iproute2}/bin/ip rule del from ${externalIp} to 192.168.0.0/16 table main priority 10 - ${pkgs.iproute2}/bin/ip rule del from ${externalIp} table ${rtTable.name} priority 20 - ''; + postSetup = lib.concatLines [ + "export PATH=${path}" + "set -x" + (lib.concatMapStringsSep "\n" addRule rules) + /* + ip route change default dev ${interface} src ${externalIp} table ${rtTable.name} + */ + '' + + nft add table ip wg_nat-${interface} + nft add chain ip wg_nat-${interface} postrouting '{type nat hook postrouting priority srcnat;}' + nft add rule ip wg_nat-${interface} postrouting ip saddr 192.168.0.0/16 oifname "public-ip4" counter snat to ${externalIp} + + nft add table inet wg_filter-${interface} + nft add chain inet wg_filter-${interface} forward '{type filter hook forward priority 0; policy accept;}' + + nft add table inet marks-${interface} + nft add chain inet marks-${interface} output '{type route hook output priority mangle;}' + nft add rule inet marks-${interface} output meta skuid yate mark set 0x1 + '' + ]; + postShutdown = lib.concatLines [ + "export PATH=${path}" + "set -x" + (lib.concatMapStringsSep "\n" deleteRule rules) + + '' + nft delete table ip wg_nat-${interface} + nft delete table inet wg_filter-${interface} + + nft delete table inet marks-${interface} + '' + ]; peers = [ { inherit publicKey;