#!/usr/sbin/nft -f flush ruleset; table inet filter { chain input { type filter hook input priority 0; policy drop; # Accept loopback. iif lo accept; # Accept traffic originated from us. ct state { established, related } accept; # Accept neighbour discovery otherwise IPv6 connectivity breaks. ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept; # Accept all ICMP types. ip protocol icmp accept; ip6 nexthdr icmpv6 accept; # Accept SSH traffic. tcp dport 122 accept; # Accept WireGuard traffic. udp dport 51820 accept; # Accept DNS traffic on the WireGuard interface. iifname wg0 meta l4proto { tcp, udp } @th,16,16 53 accept; # Accept udptunnel traffic (to circumvent some firewalls). tcp dport 443 accept; # Count dropped packets. counter drop; } chain forward { type filter hook forward priority 0; policy drop; # Accept packet forwarding on the WireGuard interface. iifname wg0 accept; oifname wg0 ct state { established, related } accept; # Count dropped packets. counter drop; } chain output { type filter hook output priority 0; policy accept; } } table inet nat { chain prerouting { type nat hook prerouting priority -100; policy accept; # Early drop of invalid packets. ct state invalid counter drop; # Accept WireGuard traffic via port 53/UDP (to circumvent some firewalls). iifname != wg0 udp dport 53 redirect to 51820; } chain postrouting { type nat hook postrouting priority 100; policy accept; # Masquerade WireGuard traffic. oif != lo ip saddr 10.10.10.1/24 masquerade; oif != lo ip6 saddr fd10:10:10::1/64 masquerade; } }