firewallnftablesnft

How right to make second input chain in other table nftables?


There is my test nft ruleset , and all works except table inet test but table f2b-table is absolytly similar (except drop vs accept) and it works fine :

table inet f2b-table {
    set addr-set-sshd {
        type ipv4_addr
        elements = { 0.0.0.0 }
    }

    chain input {
        type filter hook input priority filter - 1; policy accept;
        tcp dport { 222 } ip saddr @addr-set-sshd drop
    }
}
table inet default {
    set full_op_port {
        type inet_service
        elements = { 222 }
    }

    set allowed_ips {
        type ipv4_addr
        elements = { 0.0.0.0 }
    }

    chain INPUT {
        type filter hook input priority filter; policy drop;
        ct state invalid drop
        ct state { established, related } accept
        iif "lo" accept
        tcp dport @full_op_port accept
        ip saddr @allowed_ips accept
        ip protocol icmp accept
        counter packets 17 bytes 884
    }

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

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
    }
}
table ip test {
    chain PREROUTING {
        type nat hook prerouting priority filter; policy accept;
    }

    chain POSTROUTING {
        type nat hook postrouting priority srcnat; policy accept;
    }

    chain FORWARD {
        type filter hook forward priority filter; policy drop;
    }
}
table inet test {
    set op_port {
        type inet_service
        elements = { 8888 }
    }

    chain INPUT {
        type filter hook input priority filter - 2; policy accept;
        tcp dport @op_port accept
    }
}

I see packages in tcpdump, i see packages when i makes count in table table inet test but packages don't be accepted. What do i make wrong?


Solution

  • I am adding another answer with examples here to clarify the unintended consequences of mixing policies with multiple base-chains of the same family, type and hook. Although priority can be made the same on these, it never should. Lower priority numbers mean a higher priority and will be run first. Applying drop policies incorrectly can cause unintended consequences for traffic you intend to accept.

    As to the effect of mixing the hybrid family inet with ip and ip6, I won't even begin to pontificate except to say it's probably a bad idea.

    WARNING: The examples horribly break ipv4 traffic and were performed on a VM - buyer beware !

    An example of a bad drop policy:

    table inet filter {
            chain input1 {
                    type filter hook input priority filter + 1; policy drop;
                    tcp dport 80 log prefix "input1_" # SEEN
            }
    
        # input2 chain not evaluated as there is no traffic left after input1
            chain input2 {
                    type filter hook input priority filter + 2; policy accept;
                    tcp dport 80 accept
                    tcp dport 80 log prefix "input2_"
            }
    }
    

    An example of a ok drop policy:

    table inet filter {
            chain input1 {
                    type filter hook input priority filter + 1; policy accept;
                    tcp dport 80 log prefix "input1_" # SEEN
            }
            chain input2 {
                    type filter hook input priority filter + 2; policy drop;
                    tcp dport 80 accept
                    tcp dport 80 log prefix "input2_" # NOT SEEN due previous accept
            }
    }
    

    An example of a bad accept policy:

    table inet filter {
            chain input1 {
                    type filter hook input priority filter + 1; policy accept;
                    tcp dport 80 accept
                    tcp dport 80 log prefix "input1_" # NOT SEEN due to previous accept
            }
            chain input2 {
                    type filter hook input priority filter + 2; policy drop;
                    tcp dport 80 log prefix "input2_" # SEEN - chain evaluates
            # all traffic dropped here by policy including accepted input1 traffic
            }
    }
    

    An example of an okay accept policy:

    table inet filter {
            chain input1 {
                    type filter hook input priority filter + 1; policy accept;
                    tcp dport 80 log prefix "input1_" # SEEN
            }
            chain input2 {
                    type filter hook input priority filter + 2; policy drop;
                    tcp dport 80 accept
                    tcp dport 80 log prefix "input2_" # NOT SEEN due to previous accept
            }
    }
    

    As stated in the man page for nft, a drop by rule or policy drops immediately without further processing of lower priority base chains. accept does not. it short circuits remaining rules at the current priority and hands off to the next lower priority but here it is still subject to being dropped if explicitly dropped by rule or implicitly dropped by policy if there is no rule to accept.

    Perhaps the easiest way to approach it is use a single base chain and jump/goto non-base chains, effectively the way iptables worked.