{ config, lib, ... }: with import ./network.nix; with lib; let openTCP = concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCP; openUDP = concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDP; openTCPVPN = concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCPVPN; openUDPVPN = concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDPVPN; in { networking = { # needed to use nftables firewall.enable = false; nat.enable = false; nftables = { enable = true; ruleset = '' table ip raw { chain PREROUTING { type filter hook prerouting priority raw; policy accept; } chain OUTPUT { type filter hook output priority raw; policy accept; } } table ip nat { chain PREROUTING { type nat hook prerouting priority dstnat; policy accept; } chain INPUT { type nat hook input priority 100; policy accept; } chain OUTPUT { type nat hook output priority -100; policy accept; } chain POSTROUTING { type nat hook postrouting priority srcnat; policy accept; oifname ${wan-if} ip saddr {${ lib.concatStringsSep "," towan-wg }} masquerade oifname ${wan-if} ip saddr ${docker-net} masquerade oifname ${wan-if} ip saddr ${tailscale-net} masquerade } } table ip mangle { chain PREROUTING { type filter hook prerouting priority mangle; policy drop; ct state invalid,untracked drop comment "drop invalid" ip daddr 255.255.255.255 accept comment "allow broadcast traffic" ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" iifname ${wan-if} ip saddr ${vpn-net} drop comment "bind any ip to intf ${wan-if}" iifname ${wan-if} ip saddr 127.0.0.0/8 drop comment "bind any ip to intf ${wan-if}" iifname ${wan-if} accept comment "bind any ip to intf ${wan-if}" iifname ${proxy-if} ip saddr ${proxy-net} accept comment "bind ip ${proxy-net} to intf ${proxy-if}" iifname ${vpn-if} ip saddr ${vpn-net} accept comment "bind ip ${vpn-net} to intf ${vpn-if}" iifname ${docker-if} ip saddr ${docker-net} accept comment "bind ip ${docker-net} to intf ${docker-if}" iifname ${tailscale-if} ip saddr ${tailscale-net} accept iifname "lo" accept comment "bind any ip to intf lo" jump mangle_drop } chain INPUT { type filter hook input priority mangle; policy accept; } chain FORWARD { type filter hook forward priority mangle; policy accept; } chain OUTPUT { type route hook output priority mangle; policy accept; } chain POSTROUTING { type filter hook postrouting priority mangle; policy accept; } chain mangle_drop { ip protocol icmp jump mangle_drop_icmp ip protocol udp jump mangle_drop_udp ip protocol tcp jump mangle_drop_tcp log prefix "MANGLE-DROP-UNK " drop } chain mangle_drop_icmp { log prefix "MANGLE-DROP-ICMP " drop } chain mangle_drop_tcp { log prefix "MANGLE-DROP-TCP " drop } chain mangle_drop_udp { log prefix "MANGLE-DROP-UDP " drop } } table ip filter { chain INPUT { type filter hook input priority filter; policy drop; ct state established,related accept iifname "lo" accept comment "loopback" ip daddr 255.255.255.255 accept comment "allow broadcast traffic" ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" ip saddr ${lan-net} accept comment "lan > local" ip saddr ${tailscale-net} accept comment "tailscale > local" ip saddr {${lib.concatStringsSep "," gdevices}} accept comment "vpn > local" iifname ${wan-if} tcp dport {${openTCP}} accept iifname ${wan-if} udp dport {${openUDP}} accept iifname ${vpn-if} tcp dport {${openTCPVPN}} accept iifname ${vpn-if} udp dport {${openUDPVPN}} accept iifname ${vpn-if} icmp type echo-request accept iifname ${docker-if} udp dport 53 accept jump filter_drop } chain FORWARD { type filter hook forward priority filter; policy drop; ct state established,related accept # gdevices talking to everyone in VPN ip saddr {${ lib.concatStringsSep "," gdevices }} ip daddr ${vpn-net} accept ip saddr {${ lib.concatStringsSep "," gamenet-wg }} ip daddr {${lib.concatStringsSep "," gamenet-wg}} accept # nat to wan oifname ${wan-if} ip saddr {${ lib.concatStringsSep "," towan-wg }} accept oifname ${wan-if} ip saddr ${docker-net} accept oifname ${wan-if} ip saddr ${tailscale-net} accept jump filter_drop } chain OUTPUT { type filter hook output priority filter; policy drop; ct state established,related accept accept comment "local > *" jump filter_drop } chain filter_drop { ip protocol icmp jump filter_drop_icmp ip protocol udp jump filter_drop_udp ip protocol tcp jump filter_drop_tcp log prefix "DROP-UNK " drop } chain filter_drop_icmp { log prefix "DROP-icmp " drop } chain filter_drop_tcp { log prefix "DROP-tcp " drop } chain filter_drop_udp { log prefix "DROP-udp " drop } } ''; }; }; }