All of lore.kernel.org
 help / color / mirror / Atom feed
* [nft] Regarding `tcp flags` (and a potential bug)
@ 2021-07-27 11:18 Tom Yan
  2021-07-27 14:52 ` Tom Yan
  0 siblings, 1 reply; 6+ messages in thread
From: Tom Yan @ 2021-07-27 11:18 UTC (permalink / raw)
  To: netfilter, netfilter-devel

Hi all,

I'm a bit uncertain how `tcp flags` works exactly. I once thought `tcp
flags syn` checks whether "syn and only syn is set", but after tests,
it looks more like it checks only whether "syn is set" (and it appears
that the right expression for the former is `tcp flags == syn`):

# nft add rule meh tcp_flags 'tcp flags syn'
# nft add rule meh tcp_flags 'tcp flags ! syn'
# nft add rule meh tcp_flags 'tcp flags == syn'
# nft add rule meh tcp_flags 'tcp flags != syn'
# nft list table meh
table ip meh {
    chain tcp_flags {
        tcp flags syn
        tcp flags ! syn
        tcp flags == syn
        tcp flags != syn
    }
}

Then I test the above respectively with a flag mask:

# nft add rule meh tcp_flags 'tcp flags & (fin | syn | rst | ack) syn'
# nft add rule meh tcp_flags 'tcp flags & (fin | syn | rst | ack) ! syn'
# nft add rule meh tcp_flags 'tcp flags & (fin | syn | rst | ack) == syn'
# nft add rule meh tcp_flags 'tcp flags & (fin | syn | rst | ack) != syn'
# nft list table meh
table ip meh {
    chain tcp_flags {
        tcp flags & (fin | syn | rst | ack) syn
        tcp flags & (fin | syn | rst | ack) ! syn
        tcp flags syn / fin,syn,rst,ack
        tcp flags syn / fin,syn,rst,ack
    }
}

I don't suppose the mask in the first two rules would matter. And with
`tcp flags syn / fin,syn,rst,ack`, I assume it would be false when
"syn is cleared and/or any/all of fin/rst/ack is/are set"?

Also, as you can see, for the last two rules, `nft` interpreted them
as an identical rule, which I assume to be a bug. These does NOT seem
to workaround it either:

# nft flush chain meh tcp_flags
# nft add rule meh tcp_flags 'tcp flags == syn / fin,syn,rst,ack'
# nft add rule meh tcp_flags 'tcp flags != syn / fin,syn,rst,ack'
# nft list table meh
table ip meh {
    chain tcp_flags {
        tcp flags syn / fin,syn,rst,ack
        tcp flags syn / fin,syn,rst,ack
    }
}

I'm not sure if `! --syn` in iptables (legacy) is affected by this as
well. Anyway, I'm doing the following for now as a workaround:

# nft flush chain meh tcp_flags
# nft add rule meh tcp_flags 'tcp flags ! syn reject with tcp reset'
# nft add rule meh tcp_flags 'tcp flags { fin, rst, ack } reject with tcp reset'
# nft list table meh
table ip meh {
    chain tcp_flags {
        tcp flags ! syn reject with tcp reset
        # syn: 1, other bits: not checked
        tcp flags { fin, rst, ack } reject with tcp reset
        # syn: 1, fin: 0, rst: 0, ack: 0, other bits: not checked
        ct state != invalid accept
    }
}

Are the comments in above correct? Are any of the assumptions in this
email incorrect?

As a side question, is it even possible that any packet will be
considered `invalid` with (syn: 1, fin: 0, rst: 0, ack: 0)?

Thanks in advance!

Regards,
Tom

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-29  7:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-27 11:18 [nft] Regarding `tcp flags` (and a potential bug) Tom Yan
2021-07-27 14:52 ` Tom Yan
2021-07-27 15:10   ` Florian Westphal
2021-07-27 21:11   ` Pablo Neira Ayuso
2021-07-29  2:27     ` Tom Yan
2021-07-29  7:12       ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.