#!/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;
	}
}