table inet filter { set lograte4 { type ipv4_addr; size 65535; flags dynamic; } set lograte6 { type ipv6_addr; size 65535; flags dynamic; } chain block { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: " counter drop } chain ping-flood { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: " counter drop } chain smurf { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: " counter drop } chain bogus-tcp { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " counter drop } chain syn-flood { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: " counter drop } chain check-tcp { tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp tcp flags & (ack|fin) == fin counter goto bogus-tcp tcp flags & (ack|psh) == psh counter goto bogus-tcp tcp flags & (ack|urg) == urg counter goto bogus-tcp tcp flags & (fin|ack) == fin counter goto bogus-tcp tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan" tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan" tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan" tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan" tcp flags == (fin|urg|psh) counter goto bogus-tcp tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID" tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp ct state new tcp flags != syn counter goto bogus-tcp tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood } chain check-broadcast { #ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast" fib saddr type broadcast counter goto smurf #ip saddr 224.0.0.0/4 counter goto smurf } chain limit-ping { ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood # Note the use `meta nfproto ipv6 meta l4proto ipv6-icmp` # instead of the buggy `ip6 nexthdr ipv6-icmp`. # See https://unix.stackexchange.com/questions/645561/nftables-how-to-set-up-simple-ip-and-port-forwarding#comment1209441_645561 meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood } chain non-public { add @lograte4 { ip saddr limit rate 1/minute } add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "non-public: " counter drop } chain check-public { ip saddr 0.0.0.0/8 counter goto non-public comment "Self identification" ip saddr 0.0.0.0/32 counter goto non-public comment "Broadcast" ip saddr 10.0.0.0/8 counter goto non-public comment "Private Networks (rfc1918)" ip saddr 127.0.0.0/8 counter goto non-public comment "Loopback" ip saddr 128.0.0.0/16 counter goto non-public comment "IANA Reserved (rfc3330)" ip saddr 169.254.0.0/16 counter goto non-public comment "Local" ip saddr 172.16.0.0/12 counter goto non-public comment "Private Networks (rfc1918)" ip saddr 192.0.2.0/24 counter goto non-public comment "TEST-NET-1 (rfc5737)" ip saddr 192.168.0.0/16 counter goto non-public comment "Networks (rfc1918)" ip saddr 198.51.100.0/24 counter goto non-public comment "TEST-NET-2 (rfc5737)" ip saddr 203.0.113.0/24 counter goto non-public comment "TEST-NET-3 (rfc5737)" ip saddr 224.0.0.0/3 counter goto non-public comment "Multicast" ip saddr 240.0.0.0/5 counter goto non-public comment "Class E Reserved" ip saddr 191.255.0.0/16 counter goto non-public comment "Reserved (rfc3330)" ip saddr 192.0.0.0/24 counter goto non-public comment "IANA Reserved (rfc3330)" ip saddr 198.18.0.0/15 counter goto non-public comment "Network Interconnect Device Benchmark Testing" ip saddr 223.255.255.0/24 counter goto non-public comment "Special Use Networks (rfc3330)" ip6 saddr ::/0 counter goto non-public comment "Default (can be advertised as a route in BGP to peers if desired)" ip6 saddr ::/96 counter goto non-public comment "IPv4-compatible IPv6 address – deprecated by rfc4291" ip6 saddr ::/128 counter goto non-public comment "Unspecified address" ip6 saddr ::1 /128 counter goto non-public comment "Local host loopback address" ip6 saddr ::ffff:0.0.0.0 /96 counter goto non-public comment "IPv4-mapped addresses" ip6 saddr ::224.0.0.0 /100 counter goto non-public comment "Compatible address (IPv4 format)" ip6 saddr ::127.0.0.0 /104 counter goto non-public comment "Compatible address (IPv4 format)" ip6 saddr ::0.0.0.0 /104 counter goto non-public comment "Compatible address (IPv4 format)" ip6 saddr ::255.0.0.0 /104 counter goto non-public comment "Compatible address (IPv4 format)" ip6 saddr 0000:: /8 counter goto non-public comment "Pool used for unspecified, loopback and embedded IPv4 addresses" ip6 saddr 0200:: /7 counter goto non-public comment "OSI NSAP-mapped prefix set (rfc4548) – deprecated by rfc4048" ip6 saddr 3ffe::/16 counter goto non-public comment "Former 6bone, now decommissioned" ip6 saddr 2001:db8::/32 counter goto non-public comment "Reserved by IANA for special purposes and documentation" ip6 saddr 2002:e000:: /20 counter goto non-public comment "Invalid 6to4 packets (IPv4 multicast)" ip6 saddr 2002:7f00:: /24 counter goto non-public comment "Invalid 6to4 packets (IPv4 loopback)" ip6 saddr 2002:0000:: /24 counter goto non-public comment "Invalid 6to4 packets (IPv4 default)" ip6 saddr 2002:ff00:: /24 counter goto non-public comment "Invalid 6to4 packets" ip6 saddr 2002:0a00:: /24 counter goto non-public comment "Invalid 6to4 packets (IPv4 private 10.0.0.0/8 network)" ip6 saddr 2002:ac10:: /28 counter goto non-public comment "Invalid 6to4 packets (IPv4 private 172.16.0.0/12 network)" ip6 saddr 2002:c0a8:: /32 counter goto non-public comment "Invalid 6to4 packets (IPv4 private 192.168.0.0/16 network)" ip6 saddr fc00:: /7 counter goto non-public comment "Unicast Unique Local Addresses (ULA) – rfc4193" ip6 saddr fe80:: /10 counter goto non-public comment "Link-local Unicast" ip6 saddr fec0:: /10 counter goto non-public comment "Site-local Unicast – deprecated by rfc3879 (replaced by ULA)" ip6 saddr ff00:: /8 counter goto non-public comment "Multicast" } chain accept-icmpv6 { # Traffic That Must Not Be Dropped # https://tools.ietf.org/html/rfc4890#section-4.4.1 icmpv6 type destination-unreachable counter accept icmpv6 type packet-too-big counter accept icmpv6 type time-exceeded counter accept icmpv6 type parameter-problem counter accept # Address Configuration and Router Selection messages # (must be received with hop limit = 255) icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept icmpv6 type nd-redirect ip6 hoplimit 255 log level warn prefix "icmpv6: nd-redirect: " counter drop icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept # Link-local multicast receiver notification messages # (must have link-local source address) icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept # https://tools.ietf.org/html/rfc3810 Multicast Listener Discovery Version 2 (MLDv2) for IPv6 icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept # SEND Certificate Path notification messages # (must be received with hop limit = 255) icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation" icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement" # Multicast Router Discovery messages # (must have link-local source address and hop limit = 1) icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement" icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation" icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination" } chain input-connectivity { # Connectivity checking messages # (multicast) ping ip protocol icmp icmp type echo-reply counter accept # drop packets with rh0 headers rt type 0 jump block rt type 0 jump block rt type 0 jump block # (multicast) ping meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-reply counter accept #ct state invalid counter drop ip protocol icmp icmp type destination-unreachable counter accept ip protocol icmp icmp type time-exceeded counter accept ip protocol icmp icmp type parameter-problem counter accept ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood ip protocol icmp icmp type echo-request counter accept # echo-reply is handled before invalid packets to allow multicast ping # which do not have an associated connection. meta nfproto ipv6 meta l4proto ipv6-icmp jump accept-icmpv6 # Connectivity checking messages icmpv6 type echo-request counter accept # echo-reply is handled before invalid because of multicast } chain input { type filter hook input priority 0 policy drop iifname lo accept jump check-tcp jump limit-ping ct state { established, related } accept jump input-connectivity ct state invalid counter drop } chain output-connectivity { ip protocol icmp counter accept skuid root udp dport 33434-33523 counter accept comment "traceroute" meta nfproto ipv6 meta l4proto ipv6-icmp jump accept-icmpv6 # Connectivity checking messages meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-request counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-reply counter accept } chain output { type filter hook output priority 0 policy drop oifname lo accept tcp flags syn tcp option maxseg size set rt mtu ct state { established, related } accept jump output-connectivity } chain forward-connectivity { ip protocol icmp icmp type destination-unreachable counter accept ip protocol icmp icmp type time-exceeded counter accept ip protocol icmp icmp type parameter-problem counter accept ip protocol icmp icmp type echo-request counter accept # Traffic That Must Not Be Dropped # https://tools.ietf.org/html/rfc4890#section-4.3.1 meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type destination-unreachable counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type packet-too-big counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type time-exceeded counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type parameter-problem counter accept # Connectivity checking messages meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-request counter accept meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type echo-reply counter accept # Traffic That Normally Should Not Be Dropped # https://tools.ietf.org/html/rfc4890#section-4.3.2 meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request" meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply" meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation" meta nfproto ipv6 meta l4proto ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement" } chain forward { type filter hook forward priority 0 policy drop } } table inet nat { chain prerouting { type nat hook prerouting priority filter policy accept } chain postrouting { type nat hook postrouting priority srcnat policy accept } }