Re: Combine ipv4 and ipv6 in a set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 30, 2024 at 03:17:32PM +0000, Kerin Millar wrote:
> On Tue, 30 Jan 2024, at 1:08 PM, Marc Haber wrote:
> > This is one of my pet peeves with nft, actually. For iptables, there was
> > tooling like ferm which made it possible to write dual-stack rule sets
> > very easily. This kind of tooling seems to be completely missing in the
> > nftables world. Am I missing something here?
> 
> Quite possibly. Currently, nftables supports:
> 
> - mixed rulesets (using tables bearing the "inet" family)
> - mixed rules (wherever it makes sense)
> - first-class sets of any kind (irrespective of the type of table enclosing them)

That nicely shows another issue with nft: Docs. Neither the search
function on the nftables wiki nor the nft manual page have matches for
"mixed" or "first-class".

How would I use a mixed ruleset? How would I use a mixed rule?

> Granted, one cannot create a set that is typed in such a way that an
> element can be either an IPv4 or IPv6 address/interval. Conversely,
> iptables does not natively support sets at all, though it can
> integrate with sets that are managed by ipset(8). Now, can an ipset
> contain addresses of mixed types? No, it cannot.

In ferm, a tool that has been available for over 20 years, you can
(beginning ten years ago, I think) write things like:

@def $h_cadencia=(192.168.251.9 2001:db8:42bc:a102::9:100);
@def $h_chasse=(192.168.181.161 2001:db8:42bc:a181::a1:100);
@def $g_dnsrec=($h_cadencia $h_chasse)

domain (ip ip6) {
  table filter {
    chain FORWARD {
      iface internal0 daddr $g_dnsrec proto (tcp udp) dport 53 ACCEPT;
    }
  }
}

which creates (if I calculated correctly) four IPv4 rules and four IPv6
rules automatically. Ferm solves this trivially by dropping any
generated rules where address type and domain doesn't match.

This approach of course makes the sheer number of rules explode, but it
makes writing rules easier. My time is precious, CPU time is generously
available. In the situation where CPU time is precious as well, I might
be willing to spend some more time writing _efficient_ rules but that's
like 2 percent of all the cases and I am not willing to make my life
harder in the other 98 percent.

> As far as the present topic is concerned, the only tangible advantage
> that ipset has is the ability to create a set whose sole purpose is to
> act as a superset of other - potentially mixed - sets. This advantage
> is rather diminished by the fact that one also has to two manage two
> entirely separate rulesets with iptables and ip6tables,
> notwithstanding that wrappers such as fermi exist.

Of course one could have an nft preprocessor solving those issues, but
given that nft is already open source, reads a text file and configures
the nftables kernel backend, the natural approach would be to modify nft
to not only translate input 1:1 to kernel entries, but also add some
bells and whistles that makes life easier for those people writing
firewall rules.

With iptables, where people are encouraged to put their firewall rules
into shell scripts, things were entirely different, and this approach
was very inconvenient (proven by the fact that many iptables frontends
didnt write iptables scripts but files that could be read by
iptables-restore.

> At any rate, the follow nftables ruleset is valid.
> 
> table inet filter {
>         set block4 {
>                 type ipv4_addr
>         }
>         set block6 {
>                 type ipv6_addr
>         }
>         chain INPUT {
>                 type filter hook input priority filter; policy accept
>                 ip saddr @block4 drop
>                 ip6 saddr @block6 drop
>         }
> }

Isnt that clumsy! Wouldn't it be so much nicer to be able to write:

table inet filter {
        set block46 {
                type ipv46_addr
        }
        chain INPUT {
                type filter hook input priority filter; policy accept
                ip46 saddr @block46 drop
        }
}

Having to write distinct rules makes things more complex and
error-prone.

> >> However, the value of an ipv6_addr element is permitted to be an IPv4-mapped IPv6 address.
> >
> > Does nft have a function to convert an IPv4 address to an IPv4-mapped
> > address? Will the rule set do the intended thing? Is an ipv6 rule with
> > an IPv4 mapped address fully equivalent with a proper IPv4 rule?
> 

> I do not know, as I have not yet attempted to use them in an ipv6_addr
> set (it would waste memory).

I surely hope that are beyond the discussion of having to waste memory.
The vast majority of machines have way than enough memory to hold a few
128 bit entries, and if that is really a premium, a given mixed set can
be pulled apart automatically in preprocessing.

First make it work, then make it efficient. Don't trade human time
against machine time unless in very rare corner cases (I currently
happen to work in one of those corner cases, but I still say it's the
wrong way).

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux