flush ruleset # inet family allows ip and ip6 rules table inet firewall { chain inbound_ipv4 { # accepting ping (icmp-echo-request) for diagnostic purposes. # However, it also lets probes discover this host is alive. # This sample accepts them within a certain rate limit: # icmp type echo-request limit rate 5/second accept } chain inbound_ipv6 { # accept neighbour discovery otherwise connectivity breaks # icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept # accepting ping (icmpv6-echo-request) for diagnostic purposes. # However, it also lets probes discover this host is alive. # This sample accepts them within a certain rate limit: # icmpv6 type echo-request limit rate 5/second accept } chain inbound { # By default, drop all traffic unless it meets a filter # criteria specified by the rules that follow below. type filter hook input priority 0; policy drop; # Allow traffic from established and related packets, drop invalid ct state vmap { established : accept, related : accept, invalid : drop } tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop # Allow loopback traffic. iifname lo accept # Jump to chain according to layer 3 protocol using a verdict map meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } # Allow SSH on port TCP/22 and allow HTTP(S) TCP/80 and TCP/443 # for IPv4 and IPv6. # 8000 mpd # 8200 minidlna # 8883 mosquitto tcp dport { 22, 80, 443, 8000, 8200, 8883} accept meta l4proto { tcp, udp } th dport 53 counter packets 0 bytes 0 accept comment "accept DNS" # UPnP/ multicast udp dport 1900 meta pkttype multicast limit rate 4/second burst 20 packets accept comment "Accept UPnP IGD port mapping reply" # IGMP, could also jump to a chain that silently drops meta l4proto 2 ip daddr 224.0.0.0/24 accept comment "accept IGMP" meta l4proto 2 ip daddr 239.255.255.250 accept comment "accept IGMP digital radio" # Uncomment to enable logging of denied inbound traffic log prefix "[nftables] Inbound Denied: " counter drop } chain forward { # Drop everything (assumes this device is not a router) type filter hook forward priority 0; policy drop; } # no need to define output chain, default policy is accept if undefined. } # Separate table for hook ingress to filter bad packets early. table netdev filter { # List of ipv4 addresses to block. set blocklist_v4 { # The "ipv4_addr" are for ipv4 addresses and "flags interval" allows to set intervals. type ipv4_addr; flags interval; elements = { 169.254.0.0/16, 172.16.0.0/12,192.0.2.0/24, 10.0.0.0/8 } # suppress conflicting ip ranges, # e.g. 224.0.0.0/3,240.0.0.0/5 -> 224.0.0.0-255.255.255.255 #auto-merge } chain ingress { # For some reason the interface must be hardcoded here, variable do not work. type filter hook ingress device enp8s0 priority -500; # Drop all fragments. ip frag-off & 0x1fff != 0 counter drop # Drop bad addresses. #ip saddr @blocklist_v4 counter drop # Drop XMAS packets. tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop # Drop NULL packets. tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # Drop uncommon MSS values. tcp flags syn tcp option maxseg size 1-535 counter drop } }