0

I can't find any documentation that would explain the syntax and evaluation of the following sample constructs:

add rule filter output tcp flags & (syn | ack) == syn | ack
add rule filter output tcp flags & (fin | syn) != 0

I did read @A.B answer here: logging TCP flags.

This only explains the purpose of those constructs (matching TCP flags), but I'd like to know the syntax and how the evaluation of the expressions together with operators work.

Particularly the meaning of "bitwise" operators and how they're evaluated in the flags expressions as whole.

Also it's not clear to me what != 0 does and in particular the purpose of & operator upfront.

I know they're OR, AND etc. but don't understand how this applies in nftables rule.

Some more complex examples could help too.

meuh
54.5k2 gold badges70 silver badges135 bronze badges
asked Aug 14, 2024 at 7:07

1 Answer 1

1

Using bitwise operators in this fashion is a common approach to extract specific bit values. Thus with TCP flags, if you only care about SYN and ACK (???A??S?), you "and" the flags with "SYN or ACK", which clears all other flags (000A00S0). You can then compare the result with 0 if you only care whether one of the bits is set, or with a specific combination of flags if you want an exact match.

In the first rule, the expression is tcp flags & (syn | ack) == syn | ack. Working up by precedence:

  • (syn | ack) calculates the combination of bits representing SYN or ACK
  • tcp flags & (syn | ack) calculates the intersection of the TCP flags and "SYN or ACK": the result is only the SYN and/or ACK flags, if one or both are set
  • tcp flags & (syn | ack) == syn | ack compares the result of the previous expression with syn | ack

The overall effect is that the expression returns true if both SYN and ACK flags are set. All other flags are ignored.

Another way of looking at it is this:

SYN in flags ACK in flags Flags & (SYN or ACK) SYN or ACK ==
0 0 00 11 False
0 1 01 11 False
1 0 10 11 False
1 1 11 11 True

In the second rule, the expression is tcp flags & (fin | syn) != 0. Working up again:

  • (fin | syn) calculates the combination of bits representing FIN or SYN
  • tcp flags & (fin | syn) calculates the intersection of the TCP flags and "FIN or SYN": the result is only the FIN and/or SYN flags, if one or both are set (theoretically; in practice only one can be set)
  • tcp flags & (fin | syn) != 0 succeeds if the result of the previous expression is non-zero

The overall effect is that the expression returns true if either FIN or SYN flags are set. All other flags are ignored.

Another way of looking at it is this:

FIN in flags SYN in flags Flags & (FIN or SYN) != 0
0 0 00 False
0 1 01 True
1 0 10 True
1 1 11 True
answered Aug 14, 2024 at 7:22
5
  • Can we omit the upfront & operator such that it's tcp flags (syn | ack)? I assume this will mean that either SYN or ACK is matched but not both right? and btw. can operators other than & be put in front of flags? ex. tcp flags == (syn | ack)? Commented Aug 14, 2024 at 7:42
  • What do you mean by "upfront"? Commented Aug 14, 2024 at 9:25
  • in the flags & the & operator is in front of flags, this is what I meant by "upfront" of the rest of expression that follows, sorry for bad English. the & operator is put "upfront" of the rest of bitwise expression. (I call it upfront because my understanding is according to how bitwise expressions works in C\C++ Commented Aug 14, 2024 at 10:17
  • 1
    It’s supposed to be read left-to-right, so in flags &, flags comes first, then the & operator, same as in C. Commented Aug 14, 2024 at 10:20
  • Ah, I definitely get it now, therefore flags | syn or flags == syn are valid expressions, so flags IS part of bitwise expression. I very much appreciate you answer! Commented Aug 14, 2024 at 10:47

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.