#!/usr/sbin/nft -f ## Variables # Hosts # Interfaces define if_netwan = "netwan" define if_netlan = "netlan" define if_wg55_management = "wg55" define if_netwan_400_fux_uplink = "netwan.400" define if_netlan_51_clients = "netlan.51" define if_netlan_52_iot = "netlan.52" define if_netlan_53_public = "netlan.53" define if_netlan_54_management = "netlan.54" # Interface Groups define wan_ifs = { $if_netwan_400_fux_uplink } define lan_ifs = { $if_netlan_51_clients, $if_netlan_52_iot, $if_netlan_53_public, $if_netlan_54_management } define v4_exposed_ifs = { $if_netlan_53_public } define v6_exposed_ifs = { $if_netlan_53_public } define v4_nat_ifs = { $if_netlan_51_clients, $if_netlan_52_iot, $if_netlan_54_management } ## Rules table inet reverse-path-forwarding { chain rpf-filter { type filter hook prerouting priority mangle + 10; policy drop; # Only allow packets if their source address is routed via their incoming interface. # https://github.com/NixOS/nixpkgs/blob/d9d87c51960050e89c79e4025082ed965e770d68/nixos/modules/services/networking/firewall-nftables.nix#L100 fib saddr . mark . iif oif exists accept } } table inet host { chain input { type filter hook input priority filter; policy drop; iifname "lo" accept comment "allow loopback" ct state invalid drop ct state established,related accept ip protocol icmp accept # ICMPv6 # https://datatracker.ietf.org/doc/html/rfc4890#autoid-24 # Allowlist consisting of: "Traffic That Must Not Be Dropped" and "Traffic That Normally Should Not Be Dropped" # Error messages that are essential to the establishment and maintenance of communications: icmpv6 type { destination-unreachable, packet-too-big } accept icmpv6 type { time-exceeded } accept icmpv6 type { parameter-problem } accept # Connectivity checking messages: icmpv6 type { echo-request, echo-reply } accept # Address Configuration and Router Selection messages: icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert } accept # Link-Local Multicast Receiver Notification messages: icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, mld2-listener-report } accept # SEND Certificate Path Notification messages: icmpv6 type { 148, 149 } accept # Multicast Router Discovery messages: icmpv6 type { 151, 152, 153 } accept # Allow SSH access. tcp dport 22 accept comment "allow ssh access" # Allow WireGuard access. udp dport 51820 accept comment "allow WireGuard access" # Allow DHCP server access. iifname { $lan_ifs } udp dport 67 accept comment "allow dhcp server access" } } table ip v4nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; } chain postrouting { type nat hook postrouting priority srcnat; policy accept; iifname { $v4_nat_ifs, $if_wg55_management } oifname $wan_ifs masquerade } } table inet forward { chain forward { type filter hook forward priority filter; policy drop; ct state invalid drop ct state established,related accept # Allow internet access. iifname { $lan_ifs, $if_wg55_management } oifname $wan_ifs accept comment "allow internet access" # Allow access to exposed networks from internet. meta nfproto ipv4 oifname $v4_exposed_ifs accept comment "allow v4 exposed network access" meta nfproto ipv6 oifname $v6_exposed_ifs accept comment "allow v6 exposed network access" # Allow clients and managment to most iifname { $if_netlan_51_clients, $if_netlan_54_management, $if_wg55_management } oifname $lan_ifs accept comment "allow clients and managment to lan_ifs" } }