Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bug#994273: nftables: nft -s does NOT suppress stateful output

135 views
Skip to first unread message

Harry STARR

unread,
Sep 14, 2021, 6:10:03 PM9/14/21
to
Package: nftables
Version: 0.9.8-3.1
Severity: important

Dear Maintainer,

*** Reporter, please consider answering these questions, where appropriate ***

* What led up to the situation?
Upgrade to bullseye
* What exactly did you do (or not do) that was effective (or
ineffective)?
nft -s list ruleset
* What was the outcome of this action?
Same output as
nft list ruleset
* What outcome did you expect instead?
e.g. on counters clause, suppression of packets, bytes content

*** End of the template - remove these template lines ***


-- System Information:
Debian Release: 11.0
APT prefers stable-security
APT policy: (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 5.10.0-8-amd64 (SMP w/2 CPU threads)
Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages nftables depends on:
ii dpkg 1.20.9
ii libc6 2.31-13
ii libedit2 3.1-20191231-2+b1
ii libnftables1 0.9.8-3.1

nftables recommends no packages.

Versions of packages nftables suggests:
pn firewalld <none>

-- no debconf information

Jeremy Sowden

unread,
Oct 2, 2021, 3:10:04 PM10/2/21
to
Can you provide an example?

For instance, if I have the following rule-set:

$ sudo nft list ruleset
table ip filter {
counter c {
packets 85081 bytes 125160849
}

quota q {
1048576 mbytes used 125160849 bytes
}

chain input {
type filter hook input priority filter; policy accept;
counter name "c"
counter packets 85083 bytes 125160851
quota name "q"
quota 1048576 mbytes used 125160849 bytes
}
}

With the `-s` flag, I get the following:

$ sudo nft -s list ruleset
table ip filter {
counter c {
packets 0 bytes 0 }

quota q {
1048576 mbytes
}

chain input {
type filter hook input priority filter; policy accept;
counter name "c"
counter
quota name "q"
quota 1048576 mbytes
}
}

The state for named quotas and counter and quota rules are suppressed,
and the state for named counters is replaced with zeroes.

J.
signature.asc

Harry STARR

unread,
Oct 6, 2021, 7:50:02 PM10/6/21
to
Here is my-nftables (used to instantiate the ruleset):
nft -f my-nftables

>>> my-nftables
flush ruleset
table ip filter {
set bad_guys {
type ipv4_addr
size 65535
timeout 31m
counter
elements = { 192.168.0.101, 192.168.0.102,
192.168.0.172 }
}

set black {
type ipv4_addr
size 65535
flags interval
counter
elements = { 1.2.3.4, 5.6.7.0/24 }
}

set dns_black {
type ipv4_addr
size 65535
timeout 1d
counter
elements = { 192.168.0.100 }
}

chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter drop
ct state invalid counter drop
ct state established,related counter accept
iifname "lo" counter accept
ip saddr @black counter drop
ip saddr 192.168.0.0/16 counter accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter accept
udp dport 53 ip saddr @dns_black counter drop
tcp dport 53 ip saddr @dns_black counter drop
udp dport 53 counter accept
tcp dport 53 counter accept
fib daddr type multicast counter drop
add @bad_guys { ip saddr } log level debug counter drop
}

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

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

<<<

Here is the nft list ruleset output:
>>>
root@y6:~ # nft list ruleset
table ip filter {
set bad_guys {
type ipv4_addr
size 65535
counter
timeout 31m
}

set black {
type ipv4_addr
size 65535
flags interval
counter
elements = { 1.2.3.4 counter packets 0 bytes 0, 5.6.7.0/24 counter packets 0 bytes 0 }
}

set dns_black {
type ipv4_addr
size 65535
counter
timeout 1d
elements = { 192.168.0.100 counter packets 0 bytes 0 expires 22h59m40s260ms }
}

chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter packets 0 bytes 0 drop
ct state invalid counter packets 22 bytes 3204 drop
ct state established,related counter packets 298 bytes 23763 accept
iifname "lo" counter packets 0 bytes 0 accept
ip saddr @black counter packets 0 bytes 0 drop
ip saddr 192.168.0.0/16 counter packets 69 bytes 6558 accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter packets 8 bytes 2696 accept
udp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
tcp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
udp dport 53 counter packets 0 bytes 0 accept
tcp dport 53 counter packets 0 bytes 0 accept
fib daddr type multicast counter packets 0 bytes 0 drop
add @bad_guys { ip saddr } log level debug counter packets 0 bytes 0 drop
}

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

chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}
<<<

And here is the nft -s list ruleset
>>>
root@y6:~ # nft -s list ruleset
table ip filter {
set bad_guys {
type ipv4_addr
size 65535
counter
timeout 31m
}

set black {
type ipv4_addr
size 65535
flags interval
counter
elements = { 1.2.3.4 counter packets 0 bytes 0, 5.6.7.0/24 counter packets 0 bytes 0 }
}

set dns_black {
type ipv4_addr
size 65535
counter
timeout 1d
elements = { 192.168.0.100 counter packets 0 bytes 0 expires 22h58m48s84ms }
}

chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter packets 0 bytes 0 drop
ct state invalid counter packets 22 bytes 3204 drop
ct state established,related counter packets 351 bytes 28667 accept
iifname "lo" counter packets 0 bytes 0 accept
ip saddr @black counter packets 0 bytes 0 drop
ip saddr 192.168.0.0/16 counter packets 69 bytes 6558 accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter packets 8 bytes 2696 accept
udp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
tcp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
udp dport 53 counter packets 0 bytes 0 accept
tcp dport 53 counter packets 0 bytes 0 accept
fib daddr type multicast counter packets 0 bytes 0 drop
add @bad_guys { ip saddr } log level debug counter packets 0 bytes 0 drop
}

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

chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}
<<<

NOTICE: in chain INPUT: the packet/bytes are still listed,
and in the set listings, the packet/count values and expires time is listed.

Jeremy Sowden

unread,
Oct 7, 2021, 2:30:03 PM10/7/21
to
On 2021-10-07, at 09:26:05 +1000, Harry STARR wrote:
> [...]
Thanks. It seems that the `stateless` flag gets lost in some
circumstances. Compare this:

$ sudo nft --stateless list ruleset
table ip filter {
[...]
chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter packets 92 bytes 49768 drop
ct state invalid counter packets 0 bytes 0 drop
ct state established,related counter packets 6281 bytes 4373744 accept
iifname "lo" counter packets 1 bytes 73 accept
ip saddr @black counter packets 0 bytes 0 drop
ip saddr 192.168.0.0/16 counter packets 142 bytes 39680 accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter packets 0 bytes 0 accept
udp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
tcp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
udp dport 53 counter packets 0 bytes 0 accept
tcp dport 53 counter packets 0 bytes 0 accept
fib daddr type multicast counter packets 1 bytes 73 drop
add @bad_guys { ip saddr } log level debug counter packets 1 bytes 576 drop
}
[...]
}

with this:

$ sudo nft --stateless list chain filter INPUT
table ip filter {
chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter drop
ct state invalid counter drop
ct state established,related counter accept
iifname "lo" counter accept
ip saddr @black counter drop
ip saddr 192.168.0.0/16 counter accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter accept
udp dport 53 ip saddr @dns_black counter drop
tcp dport 53 ip saddr @dns_black counter drop
udp dport 53 counter accept
tcp dport 53 counter accept
fib daddr type multicast counter drop
add @bad_guys { ip saddr } log level debug counter drop
}
}

I'll send a patch upstream.

J.
signature.asc

Harry STARR

unread,
Oct 7, 2021, 4:50:03 PM10/7/21
to
> I'll send a patch upstream.
>
> J.

I have noticed that on Gentoo and Arch this seems to be resolved.
They are using a version > 1.0.x

Maybe already fixed upstream...

H.

Jeremy Sowden

unread,
Oct 7, 2021, 6:00:03 PM10/7/21
to
On 2021-10-08, at 06:42:29 +1000, Harry STARR wrote:
> > I'll send a patch upstream.
>
> I have noticed that on Gentoo and Arch this seems to be resolved.
> They are using a version > 1.0.x
>
> Maybe already fixed upstream...

The bug that I believe is responsible is in this if-block:

https://git.netfilter.org/nftables/tree/src/rule.c#n372

When listing a set, nft will set the `stateless` flag in order to
suppress the state of any counters it defines. However, it doesn't keep
track of whether the flag was already set and clears it unconditionally
afterwards. It has not yet been fixed upstream.

The buggy commit was released in 0.9.4, which is why you saw it after
upgrading from buster (0.9.0-2) to bullseye (0.9.8-3.1).

Here's the fix I've sent upstream:

https://lore.kernel.org/netfilter-devel/20211007201222....@azazel.net/T/#u

I'm not that familiar with Arch or Gentoo, but from what I can see
looking through their package repo's and bug-trackers, they don't seem
to be carrying patches for this.

Here's the stateless output from your example with some annotation:

*** The stateless flag is set on the command-line. ***

table ip filter {
set bad_guys {
type ipv4_addr
size 65535
*** Here we set the stateless flag. ***
counter
*** Here we clear it. ***
timeout 31m
}

set black {
type ipv4_addr
size 65535
flags interval
*** Here we set the stateless flag. ***
counter
*** Here we clear it. ***
elements = { 1.2.3.4 counter packets 0 bytes 0, 5.6.7.0/24 counter packets 0 bytes 0 }
}

set dns_black {
type ipv4_addr
size 65535
*** Here we set the stateless flag. ***
counter
*** Here we clear it. ***
timeout 1d
elements = { 192.168.0.100 counter packets 0 bytes 0 expires 22h58m48s84ms }
}

chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr @bad_guys counter packets 0 bytes 0 drop
ct state invalid counter packets 22 bytes 3204 drop
ct state established,related counter packets 351 bytes 28667 accept
iifname "lo" counter packets 0 bytes 0 accept
ip saddr @black counter packets 0 bytes 0 drop
ip saddr 192.168.0.0/16 counter packets 69 bytes 6558 accept
iifname "ge0" udp sport 67-68 udp dport 67-68 counter packets 8 bytes 2696 accept
udp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
tcp dport 53 ip saddr @dns_black counter packets 0 bytes 0 drop
udp dport 53 counter packets 0 bytes 0 accept
tcp dport 53 counter packets 0 bytes 0 accept
fib daddr type multicast counter packets 0 bytes 0 drop
add @bad_guys { ip saddr } log level debug counter packets 0 bytes 0 drop
}

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

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

Once the first set ("bad_guys") has been output, the original record of
the `stateless` flag has been lost and the only stateful objects output
with no state are the counters in the three sets where the flag is
explicitly set.

J.
signature.asc

Harry STARR

unread,
Oct 7, 2021, 8:10:03 PM10/7/21
to
> The bug that I believe is responsible is in this if-block:
>
> https://git.netfilter.org/nftables/tree/src/rule.c#n372
>
>When listing a set, nft will set the `stateless` flag in order to
>suppress the state of any counters it defines. However, it doesn't keep
>track of whether the flag was already set and clears it unconditionally
>afterwards. It has not yet been fixed upstream.
>
>The buggy commit was released in 0.9.4, which is why you saw it after
>upgrading from buster (0.9.0-2) to bullseye (0.9.8-3.1).

Excellent work, J.

>Here's the fix I've sent upstream:
>
> https://lore.kernel.org/netfilter-devel/20211007201222....@azazel.net/T/#u
>
>I'm not that familiar with Arch or Gentoo, but from what I can see
>looking through their package repo's and bug-trackers, they don't seem
>to be carrying patches for this.

Looking forward to seeing this in a bullseye update...
0 new messages