#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.

flush ruleset

table inet filter {
  set LANv4 {
    type ipv4_addr
    flags interval
  
    elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
  }

  set LANv6 {
    type ipv6_addr
    flags interval
  
    elements = { fd00::/8, fe80::/10 }
  }

  chain input_lan {
    udp sport 1900 udp dport >= 1024 meta pkttype unicast limit rate 4/second burst 20 packets accept comment "Accept UPnP IGD port mapping reply"
    udp sport netbios-ns udp dport >= 1024 meta pkttype unicast accept comment "Accept Samba Workgroup browsing replies"
  }

  chain input {
    type filter hook input priority filter
    policy drop

    ct state invalid drop comment "early drop of invalid connections"
    ct state {established, related} accept comment "allow tracked connections"
    iifname lo accept comment "allow from loopback"
    ip protocol icmp accept comment "allow icmp"
    meta l4proto ipv6-icmp accept comment "allow icmp v6"

    #tcp dport ssh accept comment "allow sshd"
    udp dport mdns ip6 daddr ff02::fb accept comment "Accept mDNS"
    udp dport mdns ip daddr 224.0.0.251 accept comment "Accept mDNS"

    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    ip6 saddr @LANv6 jump input_lan comment "Connections from private IP address ranges"
    ip saddr @LANv4 jump input_lan comment "Connections from private IP address ranges"
    counter
  }

  chain forward {
    type filter hook forward priority filter
    policy drop
  }
}
