Stateful objects: Difference between revisions

From nftables wiki
Jump to navigation Jump to search
m (Intro: link counter page.)
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
Stateful objects group stateful information of rules, the supported types are: counters and quotas. Stateful objects are attached to tables and have a unique name, defined by the user.
''Stateful objects'' is nftables's umbrella term for objects that maintain information about packet flows and connection states, that are updated by each packet that "hits" them, and that share a common syntax. Strictly speaking, ''stateful object'' refers to a '''named''' object that is attached to a [[Configuring_tables|table]]. More loosely, anonymous stateful objects can also be used, e.g. an unnamed [[Counters|counter]] used in a [[Simple_rule_management|rule]]. Anonymous stateful objects exist only in the context of the object (i.e. rule) in which they are used. This difference in scope causes some quirks, see the below section on resetting stateful objects.
 
Initial support for stateful objects was added in [https://kernelnewbies.org/Linux_4.10#Networking Linux kernel 4.10] and [https://marc.info/?l=netfilter&m=150785219810541&w=2 nftables 0.8], with support for counters and quotas.


= Creating stateful objects =
= Creating stateful objects =


You can create a counter with the command:
You can create a '''stateful counter''' with the following commands:


<source lang="bash">
<source lang="bash">
Line 10: Line 12:
</source>
</source>


These rules create a table named ''filter'', then a counter named ''https-traffic'' and attaches it to ''filter''.
These rules create a table named ''filter'', then a '''stateful counter''' named ''https-traffic'' and attaches it to the ''filter'' table.


Creating a quota is similar:
Creating a '''quota''' is similar:


<source lang="bash">
<source lang="bash">
Line 22: Line 24:
= Referencing stateful objects in rules =
= Referencing stateful objects in rules =


Stateful objects are referenced in rules by their names, the simplest way is:
Stateful objects are referenced in rules by their names. They act as both actions and in the case of quotas also matches the simplest way is:


<source lang="bash">
<source lang="bash">
Line 53: Line 55:
% nft add element filter ports { 22 : "ssh-quota" }
% nft add element filter ports { 22 : "ssh-quota" }
</source>
</source>
When using quotas, the packet will be counted towards the quota, and if the quota matches (either up-to or over depending on quota type) the remaining actions will take place, otherwise not.
<source lang="bash">
table inet foo {
  quota example { over 100 mbytes used 0 bytes }
  chain dropafterquota {
      type filter hook postrouting priority 0; policy accept;
      udp port 5060 quota name "example" drop
  }
}
</source>
Will count all udp port 5060 packets towards the quota and drop all packets once the quota hits its "over 100 mbytes" threshold.


= Listing stateful objects =
= Listing stateful objects =
Line 60: Line 81:
<source lang="bash">
<source lang="bash">
% nft list counter filter https-traffic
% nft list counter filter https-traffic
table ip filter {
counter https-traffic {
packets 0 bytes 0
}
}
% nft list quota ip filter https-quota
table ip filter {
quota https-quota {
25 mbytes
}
}
</source>
</source>


Also, it's possible to list all stateful objects of the same type:
Also, it's possible to list all stateful objects of the same type. Example with quotas:


<source lang="bash">
<source lang="bash">
% nft list quotas
% nft list quotas
table inet filter {
quota other-inet-quota {
200 mbytes
}
}
table ip filter {
quota https-quota {
30 mbytes
}
quota http-quota {
25 mbytes
}
}
</source>
</source>


And list all stateful objects of a type in a table:
Example with counters:


<source lang="bash">
<source lang="bash">
% nft list counters table filter
% nft list counters
table inet filter {
counter mycounter {
packets 0 bytes 0
}
counter mycounter2 {
packets 0 bytes 0
}
}
table ip filter {
counter https-traffic {
packets 0 bytes 0
}
}
</source>
</source>


= Reseting stateful objects =
And list all stateful objects of a type in a given table. Example with counters:


Reseting an object will list its content and set it to 0:
<source lang="bash">
% nft list counters table inet filter
table inet filter {
counter mycounter {
packets 0 bytes 0
}
counter mycounter2 {
packets 0 bytes 0
}
}
</source>
 
Example with quotas:
 
<source lang="bash">
% nft list quotas table ip filter
table ip filter {
quota https-quota {
30 mbytes
}
quota http-quota {
25 mbytes
}
}
</source>
 
= Resetting stateful objects =
 
Resetting an object will atomically dump and reset its content:


<source lang="bash">
<source lang="bash">
Line 100: Line 188:
% nft reset quotas table filter
% nft reset quotas table filter
</source>
</source>
At the moment (Jan 2019) resetting quotas does not reset anonymous quotas such as used in rules without names, see [https://bugzilla.netfilter.org/show_bug.cgi?id=1314 bug #1314]

Latest revision as of 16:09, 6 April 2021

Stateful objects is nftables's umbrella term for objects that maintain information about packet flows and connection states, that are updated by each packet that "hits" them, and that share a common syntax. Strictly speaking, stateful object refers to a named object that is attached to a table. More loosely, anonymous stateful objects can also be used, e.g. an unnamed counter used in a rule. Anonymous stateful objects exist only in the context of the object (i.e. rule) in which they are used. This difference in scope causes some quirks, see the below section on resetting stateful objects.

Initial support for stateful objects was added in Linux kernel 4.10 and nftables 0.8, with support for counters and quotas.

Creating stateful objects

You can create a stateful counter with the following commands:

% nft add table filter
% nft add counter filter https-traffic

These rules create a table named filter, then a stateful counter named https-traffic and attaches it to the filter table.

Creating a quota is similar:

% nft add quota filter https-quota 25 mbytes

A quota named https-quota is attached to the table filter, notice that you must specify the quota's size on creation.

Referencing stateful objects in rules

Stateful objects are referenced in rules by their names. They act as both actions and in the case of quotas also matches the simplest way is:

% nft add chain filter output { type filter hook output priority 0 \; }
% nft add rule filter output tcp dport https counter name https-traffic

These rules create a chain named output in the table filter, then a rule to counter the https packets generated by your machine and display them in the counter https-traffic.

They can also be used with maps:

% nft add rule filter output counter name tcp dport map { \
          https : "https-traffic", \
          80 : "http-traffic", \
          25 : "foo-counter", \
          50 : "foo-counter", \
          107 : "foo-counter" \
  }

Similarly, dynamic maps can be used:

% nft add map filter ports { type inet_service : quota \; }
% nft add rule filter output quota name tcp dport map @ports
% nft add quota filter http-quota over 25 mbytes
% nft add quota filter ssh-quota 10 kbytes
% nft add element filter ports { 80 : "http-quota" }
% nft add element filter ports { 22 : "ssh-quota" }


When using quotas, the packet will be counted towards the quota, and if the quota matches (either up-to or over depending on quota type) the remaining actions will take place, otherwise not.

table inet foo {
   quota example { over 100 mbytes used 0 bytes }

   chain dropafterquota { 
      type filter hook postrouting priority 0; policy accept;
      udp port 5060 quota name "example" drop
   }

}

Will count all udp port 5060 packets towards the quota and drop all packets once the quota hits its "over 100 mbytes" threshold.

Listing stateful objects

You can list the stateful information of objects individually via:

% nft list counter filter https-traffic
table ip filter {
	counter https-traffic {
		packets 0 bytes 0
	}
}

% nft list quota ip filter https-quota
table ip filter {
	quota https-quota {
		25 mbytes
	}
}

Also, it's possible to list all stateful objects of the same type. Example with quotas:

% nft list quotas
table inet filter {
	quota other-inet-quota {
		200 mbytes
	}
}
table ip filter {
	quota https-quota {
		30 mbytes
	}
	quota http-quota {
		25 mbytes
	}
}

Example with counters:

% nft list counters
table inet filter {
	counter mycounter {
		packets 0 bytes 0
	}
	counter mycounter2 {
		packets 0 bytes 0
	}
}
table ip filter {
	counter https-traffic {
		packets 0 bytes 0
	}
}

And list all stateful objects of a type in a given table. Example with counters:

% nft list counters table inet filter
table inet filter {
	counter mycounter {
		packets 0 bytes 0
	}
	counter mycounter2 {
		packets 0 bytes 0
	}
}

Example with quotas:

% nft list quotas table ip filter
table ip filter {
	quota https-quota {
		30 mbytes
	}
	quota http-quota {
		25 mbytes
	}
}

Resetting stateful objects

Resetting an object will atomically dump and reset its content:

% nft reset quota filter https-quota
table ip filter {
	quota https-quota {
		25 mbytes used 217 kbytes
	}
}

% nft list quota filter https-quota
table ip filter {
	quota https-quota {
		25 mbytes
	}
}

Other usages are similar to the command list, e.g.

% nft reset counters
% nft reset quotas table filter

At the moment (Jan 2019) resetting quotas does not reset anonymous quotas such as used in rules without names, see bug #1314