익명 19:21

Linux nft firewall: overlapping set elements

Linux nft firewall: overlapping set elements

I have a question regarding overlapping elements in nft firewall sets. Let's have a set:

table ip filter {
        set iponly { 
                type iface_index . ipv4_addr
                flags interval
                elements = {
                    eth0 . 10.1.1.100,
                    eth0 . 10.1.1.4/30,
                    eth0 . 10.1.1.0/24,
                }
        }
}

This works. But if I use sub-networks with the same network numbers or broadcast:

eth0 . 10.1.1.100,
eth0 . 10.1.1.0/30,
eth0 . 10.1.1.252/30,
eth0 . 10.1.1.0/24,

I get an error:

x.nft:13:21-38: Error: Could not process rule: File exists
                    eth0 . 10.1.1.0/24,
                    ^^^^^^^^^^^^^^^^^^

Networks 10.1.1.0/30 and 10.1.1.0/24 have the same network number, networks 10.1.1.252/30 and 10.1.1.0/24 have the same broadcast. And I can't insert this into a set.

But if I use network "fully inside", like 10.1.1.4/30 and 10.1.1.0/24 from 1st example, this works. Also 10.1.1.100 is "fully inside" of 10.1.1.0/24 and works too.

(For the record, 10.1.1.0/32 doesn't work too but I don't want to use that ;) )

So the question is: is this intended behavior and I should live with that, or am I doing something wrong?

2nd question: About nft processing internals: Event the 1st example doesn't work if I place 10.1.1.4/30 after 10.1.1.0/24. Does it mean that comparing packets against set elements is sequential? I thought there would be some hash table for this.

Update

Kernel version: 6.18.34
nftables v1.1.6 (Commodore Bullmoose #7)



Top Answer/Comment:

I cannot say whether it intended, but it works as designed. Set elements are inserted sequentially; for each element nftables checks whether this element already exists (for interval sets it includes checking for overlapping ranges). So yes, the result of inserting elements into a interval set depends on the order of insertion.

It is unrelated to the internal representation. When inserting new element nftables basically performs lookup using the underlying methods. There are linear table, hash table and special tree-like structure for interval sets. Lookup is of course more efficient than simple linear search.

nftables supports auto-merge set property which will coalesce multiple overlapping/adjacent ranges into one:

tw:~ # cat /tmp/nft
table ip filter {
        set iponly { 
                type ipv4_addr
                flags interval
        auto-merge
                elements = {
                    10.1.1.100,
                    10.1.1.0/24,
                    10.1.1.4/30,
                }
        }
}
tw:~ # nft -f /tmp/nft 
tw:~ # nft list ruleset
table ip filter {
    set iponly {
        type ipv4_addr
        flags interval
        auto-merge
        elements = { 10.1.1.0/24 }
    }
}
tw:~ # nft destroy element ip filter iponly \{ 10.1.1.200/32 \}
tw:~ # nft list ruleset
table ip filter {
    set iponly {
        type ipv4_addr
        flags interval
        auto-merge
        elements = { 10.1.1.0-10.1.1.199, 10.1.1.201-10.1.1.255 }
    }
}
tw:~ # 

The catch is that auto-merge is implicitly disabled for concatenated types, it is only supported for sets with elements of basic types as above.

상단 광고의 [X] 버튼을 누르면 내용이 보입니다