Re: Combining/compacting 2 rules into 1

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

 



On Fri, 19 Apr 2024, at 11:55 AM, William N. wrote:
> Is it possible to combine, e.g.:
>
> tcp flags fin,syn / fin,syn drop
> tcp flags syn,rst / syn,rst drop
> tcp flags fin,rst / fin,rst drop
> tcp flags fin / fin,ack drop
>
> into something like:
>
> tcp flags {
> 	fin,syn / fin,syn,
> 	syn,rst / syn,rst,
> 	fin,rst / fin,rst,
> 	fin / fin,ack
> 	} drop
>
> just using some correct syntax?

(This might have been better off as a new thread)

To begin with, I would recommend that you jettison these rules outright. It is probable that they would otherwise end up being useless. But why?

If you are using a stateful ruleset - that is, one that matches against ctstate in any capacity - then generally invalid TCP flag combinations will always be classifed as "invalid", which is particularly useful for the forwarding path. Here is proof of this claim.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/netfilter/nf_conntrack_proto_tcp.c?h=v5.8#n700

This check is further augmented by the presence of a TCP state machine, by which a packet may also be classified as invalid. The following post explains it a little bit further.

https://marc.info/?l=netfilter&m=159842459323063&w=2

If, on the other hand, you have written a stateless ruleset for a host that is not being tasked with forwarding packets, it is by no means clear that the rules will confer any value other than, perhaps, for statistical purposes. The state machine implemented by the TCP stack should already know what it is doing.

...

That aside, it is my understanding that the rules in question cannot be expressed in the way that you are attempting. To write "tcp flags { ... }" is to attempt to match - in the sense of the "==" operator - against an anonymous set consisting of elements whose values are of the type, tcp_flag, which is an 8-bit integer.

# nft describe tcp_flag | head -n1
datatype tcp_flag (TCP flag) (basetype bitmask, integer), 8 bits

The problem you have is that, while "/" concerns the matter of bitwise arithmetic, it is not quite an arithmetic operator in its own right. Rather, it is a syntactical shortcut for treating "expression / flags" as if it were "expression & flags == flags". As such, it constitutes a test, not merely a constant value. Knowing that, you can probably see why things go off the rails in the course of trying to compose the set.

It doesn't help that this is entirely undocumented. Indeeed, arithmetic expressions are not mentioned by the manual at all, save for a vague indication that they are supported for relative priorities in the CHAINS section.

If such a thing were to be possible at all, it might entail a set of tcp_flag concatenations. For example:

{
	fin|rst . fin|rst,
	fin     . fin|ack
}

But the imaginary syntax that might be necessary to wire up such a thing isn't available. At least, not that I can gather (if mistaken, I would welcome a correction). Given the number of bugs I just discovered in the course of experimenting with all this, maybe it is just as well.

-- 
Kerin Millar




[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