#!/usr/sbin/nft -f

flush ruleset

# `inet` applies to both IPv4 and IPv6.
table inet filter {
    chain input {
        type filter hook input priority 0;

        # accept any localhost traffic
        iif lo accept

        # no ping floods:
        ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets drop
        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop

        # accept traffic originated from us
        ct state established,related accept

        # accept ICMP & IGMP
        ip6 nexthdr icmpv6 icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept
        ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept
        ip protocol igmp accept

        # ssh
        tcp dport 22 accept

        # http/https
        tcp dport 80 accept
        tcp dport 443 accept

        # smtp/submission
        tcp dport 25 accept
        tcp dport 587 accept

        # pop3/pop3s
        tcp dport 110 accept
        tcp dport 995 accept

        # imap/imaps
        tcp dport 143 accept
        tcp dport 993 accept

        # count and drop any other traffic
        counter drop
    }

    chain output {
        type filter hook output priority 0;
        policy accept;
    }

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