<html>
    <head>
      <base href="https://bugzilla.netfilter.org/" />
    </head>
    <body><span class="vcard"><a class="email" href="mailto:kfm@plushkava.net" title="kfm@plushkava.net">kfm@plushkava.net</a>
</span> changed
              <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Usability improvements, enabling creation of complex firewalls"
   href="https://bugzilla.netfilter.org/show_bug.cgi?id=1434">bug 1434</a>
          <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">CC</td>
           <td>
                
           </td>
           <td>kfm@plushkava.net
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Usability improvements, enabling creation of complex firewalls"
   href="https://bugzilla.netfilter.org/show_bug.cgi?id=1434#c1">Comment # 1</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Usability improvements, enabling creation of complex firewalls"
   href="https://bugzilla.netfilter.org/show_bug.cgi?id=1434">bug 1434</a>
              from <span class="vcard"><a class="email" href="mailto:kfm@plushkava.net" title="kfm@plushkava.net">kfm@plushkava.net</a>
</span></b>
        <pre>Disclaimer: I don't speak for the Netfilter team and any opinions expressed are
my own. I think that some of the points being made are specious. I shall focus
on those particular points, which is not to imply that there aren't any valid
points otherwise being made in the linked GitHub issue.

The claim that multiple layer 4 protocols cannot be matched is incorrect. This
is a valid rule:-

  meta l4proto { tcp, udp } th dport 53

There is no such thing as a "subchain". There are only chains, as scoped by the
enclosing table, and they must be named. If there were even such a thing as an
anonymous chain then it wouldn't be possible to jump to it from a rule defined
in another chain. This kind of abstraction is fine for an iptables/nftables
wrapper but doesn't translate well to the core.

One of the commenters presents the following ferm ruleset:

  domain (ip ip6) table filter {
    chain INPUT proto (tcp udp) dport 2003 {
      saddr ( 127.0.0.0/8 ::1/128 172.23.0.0/16 192.168.13.0/24 ) ACCEPT;
    }
  }

He proceeds to demonstrate an an equivalent ruleset for nftables that is unduly
convoluted. Yet, it could be written like this:-

  table inet filter {
    chain INPUT {
      meta l4proto { tcp, udp } th dport 2003 ip saddr { 127.0.0.0/8,
172.23.0.0/16, 192.168.13.0/24 } accept
      meta l4proto { tcp, udp } th dport 2003 ip6 saddr { ::1/128 } accept
    }
  }

Or this:-

  table inet filter {
    chain INPUT {
      meta l4proto { tcp, udp } th dport 2003 jump whitelist
    }
    chain whitelist {
      ip saddr { 127.0.0.0/8, 172.23.0.0/16, 192.168.13.0/24 } accept
      ip6 saddr { ::1/128 } accept
    }
  }

Note that this has the advantage of the "whitelist" chain being referenceable
by any other rule. Even then, the problem is made to appear more complex than
it necessarily is. For instance, I might choose to write it like this:-

  table inet filter {
    chain INPUT {
      iifname "lo" accept
      meta l4proto { tcp, udp } th dport 2003 ip saddr { 172.23.0.0/16,
192.168.13.0/24 } accept
    }
  }

A claim is made to the effect that it is not trivial to atomically replace a
ruleset. In fact, all that is required is to begin with a flush ruleset
command. In the case that is considered undesirable to have the command be a
part of the stored ruleset, then it is only a matter of synthesizing the input
stream:-

  { echo "flush ruleset"; cat /path/to/ruleset.nft; } | nft -f -

Elsewhere, a complaint is made that nft "doesn't allow empty set variables".
The following example is given:

  define BASE_ALLOWED_INCOMING_TCP_PORTS = {22, 80, 443}
  define EXTRA_ALLOWED_INCOMING_TCP_PORTS = {}
  table inet filter {
    chain input {
      type filter hook input priority 0; policy drop;
      tcp dport {$BASE_ALLOWED_INCOMING_TCP_PORTS,
$EXTRA_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept
    }
  }

However, I don't think that anyone in their right mind ought to go about it in
such a way. Instead, they would be better served by using a named set:-

  table inet filter {
    set incoming_tcp_ports {
      type inet_service
      elements = { 20, 80, 443 }
    }    
    chain input {
      type filter hook input priority 0; policy drop;
      tcp dport @incoming_tcp_ports ct state new counter accept
    }
  }

Note that a named set doesn't have to contain any elements to begin with; it
can be declared with just the type alone. Unlike variables, they are properly
represented by the "list ruleset" command, rather than being elided. Named sets
also have the advantage of being independently modifiable, among many other
things.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are watching all bug changes.</li>
      </ul>
    </body>
</html>