flush ruleset

# @link: https://fishilico.github.io/generic-config/etc/nftables-server.conf.raw.html

table inet firewall {

    # allow all outbound traffic
    chain outbound {
        type filter hook output priority 0; policy accept;
    }

    # accept ip4 icmp with rate limit
    chain inbound_ipv4 {
        icmp type echo-request limit rate 5/second accept
    }

    # accept neighbor discovery and ip6 icmp with rate limit
    chain inbound_ipv6 {
        icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
        icmpv6 type echo-request limit rate 5/second accept
    }

    # drop all inbound traffic that does not pass filters
    chain inbound {
        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 }

        # 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 }

        # silence some noisy crap
        #meta pkttype broadcast counter drop comment "silently drop unsollicited broadcast"
        #meta pkttype multicast counter drop comment "silently drop unsollicited multicast"
        #ip daddr 255.255.255.255/32 counter drop comment "really drop unsollicited IPv4 broadcast"

        # allow http and https traffic
        tcp dport { 80, 443 } accept

        # rate limit new ssh connections
        tcp dport ssh ct state new limit rate 4/minute accept

        # log all denied traffic (including ssh)
        # @note: disabled until I can find a way to silence wrong DST traffic
        #log prefix "[nftables] Inbound Denied: " counter drop
    }

    # do not act as a router; drop all forward requests
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
}
