Files
nixos/hosts/fw/modules/firewall.nix
2025-05-24 10:11:18 +02:00

192 lines
10 KiB
Nix

{ config, pkgs, ... }: {
networking = {
firewall.checkReversePath = false;
nat.enable = false;
nftables = {
enable = true;
tables = {
"cloonar-fw" = {
family = "inet";
content = ''
chain snap-qos-raw {
type filter hook prerouting priority raw; policy accept;
tcp dport 1704 counter mark set 10 comment "Mark Snapcast traffic"
tcp dport 3483 counter mark set 10 comment "Mark Squezelite traffic"
udp dport 3483 counter mark set 10 comment "Mark Squezelite traffic"
}
chain snap-qos-mangle {
type filter hook postrouting priority mangle + 10; policy accept;
mark 10 counter ip dscp set cs3 comment "Tag Snapcast with CS3"
}
chain output {
type filter hook output priority 100; policy accept;
}
chain rpfilter {
type filter hook prerouting priority mangle + 10; policy drop;
meta nfproto ipv4 udp sport . udp dport { 68 . 67, 67 . 68 } accept comment "DHCPv4 client/server"
fib saddr . mark . iif oif exists accept
}
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept comment "trusted interfaces"
iifname "lan" counter accept comment "Spice"
iifname { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
ct state vmap { invalid : drop, established : accept, related : accept, new : jump input-allow, untracked : jump input-allow }
tcp flags syn / fin,syn,rst,ack log prefix "refused connection: " level info
}
chain input-allow {
udp dport != { 53, 5353 } ct state new limit rate over 1/second burst 10 packets drop comment "rate limit for new connections"
iifname lo accept
iifname "wan" udp dport 51820 counter accept comment "Wireguard traffic"
iifname "wan" tcp dport 9273 counter accept comment "Prometheus traffic"
iifname "lan" tcp dport 5931 counter accept comment "Spice"
iifname { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
iifname { "multimedia", "smart", "infrastructure", "podman0", "setup" } udp dport { 53, 5353 } counter accept comment "DNS"
iifname { "multimedia", "smart", "infrastructure", "server", "lan", "guest" } udp dport { 67 } counter accept comment "DHCP"
iifname { "wan", "multimedia" } icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
# Accept mDNS for avahi reflection
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 tcp dport { llmnr } counter accept
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 udp dport { mdns, llmnr } counter accept
iifname "server" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "Avahi mDNS"
iifname "lan" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "Avahi mDNS"
# Allow all returning traffic
ct state { established, related } counter accept
# Allow returning traffic from wrwks and drop everthing else
iifname "wrwks" ct state { established, related } counter accept
iifname "wrwks" drop
# Allow returning traffic from wg_epicenter and drop everthing else
iifname "wg_epicenter" ct state { established, related } counter accept
iifname "wg_epicenter" drop
# Allow returning traffic from wg_ghetto_at and drop everthing else
iifname "wg_ghetto_at" ct state { established, related } counter accept
iifname "wg_ghetto_at" drop
# Allow returning traffic from wan and drop everthing else
iifname "wan" ct state { established, related } accept comment "Allow established traffic"
iifname "wan" icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
iifname "wan" counter drop comment "Drop all other unsolicited traffic from wan"
limit rate 60/minute burst 100 packets log prefix "Input - Drop: " comment "Log any unmatched traffic"
}
chain forward {
type filter hook forward priority filter; policy drop;
iifname "wg_cloonar" counter accept comment "test wireguard"
iifname "wg_cloonar" oifname lo counter accept comment "wireguard to server"
# enable flow offloading for better throughput
# ip protocol { tcp, udp } flow offload @f
# broadcast
iifname "server" oifname { "lan", "multimedia" } udp dport { 9 } counter accept comment "wakeonlan"
# multimedia airplay
iifname "multimedia" oifname { "lan" } counter accept
iifname "multimedia" oifname "server" tcp dport { 1704, 1705 } counter accept
iifname "multimedia" oifname "server" tcp dport { 3483, 9000 } counter accept
iifname "multimedia" oifname "server" udp dport { 3483 } counter accept
iifname "multimedia" oifname "server" icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
iifname "lan" oifname "server" udp dport { 5000, 5353, 6001 - 6011 } counter accept
# avahi
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 oifname { "lan" } counter accept
# Allow Chromecast
iifname "lan" oifname "server" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "mDNS query LANServer"
iifname "server" oifname "lan" udp sport 5353 ip saddr 224.0.0.251 counter accept comment "mDNS response ServerLAN"
iifname "lan" oifname "server" tcp dport 9881 counter accept comment "chromecast"
# SSDP / UPnP discovery if needed
iifname { "lan", "server" } oifname { "server", "lan" } \
udp dport 1900 ip daddr 239.255.255.250 counter accept comment "SSDP query"
iifname { "lan", "server" } oifname { "server", "lan" } \
udp sport 1900 ip saddr 239.255.255.250 counter accept comment "SSDP response"
# smart home coap
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 udp dport { 5683 } counter accept
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 tcp dport { 1883 } counter accept
# Forward to git server
oifname "server" ip daddr ${config.networkPrefix}.97.50 tcp dport { 22 } counter accept
oifname "server" ip daddr ${config.networkPrefix}.97.5 tcp dport { 80, 443 } counter accept
# lan and vpn to any
iifname { "lan", "server", "vserver", "wg_cloonar" } oifname { "lan", "vb-*", "vm-*", "server", "vserver", "infrastructure", "multimedia", "smart", "wg_cloonar", "guest", "setup" } counter accept
iifname { "lan", "server", "wg_cloonar" } oifname { "wrwks", "wg_epicenter", "wg_ghetto_at" } counter accept
iifname { "infrastructure", "setup" } oifname { "server", "vserver" } counter accept
iifname { "lan", "wan" } udp dport { 8211, 27015 } counter accept comment "palworld"
# accept palword server
iifname { "wan", "lan" } oifname "podman0" udp dport { 8211, 27015 } counter accept comment "palworld"
# forward to ark server
oifname "server" ip daddr ${config.networkPrefix}.97.201 tcp dport { 27020 } counter accept comment "ark survival evolved"
oifname "server" ip daddr ${config.networkPrefix}.97.201 udp dport { 7777, 7778, 27015 } counter accept comment "ark survival evolved"
# firefox-sync
oifname "server" ip daddr ${config.networkPrefix}.97.51 tcp dport { 5000 } counter accept comment "firefox-sync"
# allow all established, related
ct state { established, related } accept comment "Allow established traffic"
# Allow trusted network WAN access
iifname {
"lan",
"infrastructure",
"server",
"vserver",
"multimedia",
"smart",
"wg_cloonar",
"podman*",
"guest",
"setup",
"vb-*",
"vm-*",
} oifname {
"wan",
} counter accept comment "Allow trusted LAN to WAN"
limit rate 60/minute burst 100 packets log prefix "Forward - Drop: " comment "Log any unmatched traffic"
}
'';
};
"cloonar-nat" = {
family = "ip";
content = ''
chain prerouting {
type nat hook prerouting priority filter; policy accept;
iifname "server" ip daddr ${config.networkPrefix}.96.255 udp dport { 9 } dnat to ${config.networkPrefix}.96.255
iifname "wan" tcp dport { 22 } dnat to ${config.networkPrefix}.97.50
iifname "wan" tcp dport { 80, 443 } dnat to ${config.networkPrefix}.97.5
iifname "wan" tcp dport { 5000 } dnat to ${config.networkPrefix}.97.51
iifname { "wan", "lan" } udp dport { 7777, 7778, 27015 } dnat to ${config.networkPrefix}.97.201
iifname { "wan", "lan" } tcp dport { 27020 } dnat to ${config.networkPrefix}.97.201
}
# Setup NAT masquerading on external interfaces
chain postrouting {
type nat hook postrouting priority filter; policy accept;
oifname { "wan", "wg_cloonar", "wrwks", "wg_epicenter", "wg_ghetto_at" } masquerade
iifname { "lan", "wg_cloonar" } ip daddr ${config.networkPrefix}.110.101 masquerade
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.50 masquerade
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.51 masquerade
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.201 masquerade
}
'';
};
};
};
};
}