http://wiki.nftables.org/wiki-nftables/api.php?action=feedcontributions&user=Duncan&feedformat=atomnftables wiki - User contributions [en]2024-03-29T14:38:05ZUser contributionsMediaWiki 1.36.4http://wiki.nftables.org/wiki-nftables/index.php?title=Concatenations&diff=333Concatenations2018-08-14T08:08:04Z<p>Duncan: "packet is" should be "packet's" (i.e. belonging to the packet)</p>
<hr />
<div>Since Linux kernel 4.1, nftables supports concatenations.<br />
<br />
This new feature allows you to put two or more selectors together to perform very fast lookups by combining them with [[sets]], [[dictionaries]], [[maps]] and [[meters]].<br />
<br />
= Literal sets =<br />
<br />
<source lang="bash"><br />
% nft add rule ip filter input ip saddr . ip daddr . ip protocol { 1.1.1.1 . 2.2.2.2 . tcp, 1.1.1.1 . 3.3.3.3 . udp} counter accept<br />
</source><br />
<br />
So if the packet's source IP address AND destination IP address AND level 4 protocol match:<br />
<br />
* 1.1.1.1 and 2.2.2.2 and TCP.<br />
<br />
or<br />
<br />
* 1.1.1.1 and 3.3.3.3 and UDP.<br />
<br />
nftables updates the counter for this rule and then accepts the packet.<br />
<br />
= Dictionary declarations =<br />
<br />
The following example creates the ''whitelist'' dictionary using a concatenation of two selectors:<br />
<br />
<source lang="bash"><br />
% nft add map filter whitelist { type ipv4_addr . inet_service : verdict \; }<br />
</source><br />
<br />
Once you create the dictionary, you can use it from a rule that creates the following concatenation:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr . tcp dport vmap @whitelist<br />
</source><br />
<br />
Thus, the rule above looks up for a verdict based on the source IP address AND the TCP destination port.<br />
<br />
Since the dictionary is initially empty, you can dynamically populate this dictionary with elements through:<br />
<br />
<source lang="bash"><br />
% nft add element filter whitelist { 1.2.3.4 . 22 : accept}<br />
</source><br />
<br />
= Literal maps =<br />
<br />
The rule below determines the destination IP address that is used to perform DNAT to the packet based on:<br />
<br />
* the source IP address<br />
<br />
AND<br />
<br />
* the destination TCP port<br />
<br />
<source lang="bash"><br />
% nft add rule ip nat prerouting dnat ip saddr . tcp dport map { 1.1.1.1 . 80 : 192.168.1.100, 2.2.2.2 . 8888 : 192.168.1.101 }<br />
</source><br />
<br />
= Examples =<br />
<br />
Some concrete example concatenations so you get an idea on how powerful this new feature is.<br />
<br />
== Network addresses ==<br />
<br />
The example below implements a dictionary using network masks as matching element.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
Note that this is not an interval, this is masking the ip saddr and ip daddr, then concate both results. This concatenation is used to lookup for a matching of this the result in the map. This syntax may be compacted in future releases to support CIDR notation.<br />
<br />
This could be easily implemented using a named map as well:<br />
<br />
<source lang="bash"><br />
% nft add map tablename myMap { type ipv4_addr . ipv4_addr : verdict \; }<br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip saddr and 255.255.255.0 vmap @myMap<br />
% nft add element tablename myMap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
== Interfaces ==<br />
<br />
The example below checks both input and output interfaces of a forwarded packet.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname iif . oif vmap { eth0 . eth1 : accept }<br />
</source><br />
<br />
Please note that using strings (for example iifname and oifname) and other variable sized data types is not supported yet.<br />
<br />
== Some ipset types ==<br />
<br />
These ipset types can be implemented in nftables using concatenations. Probably more equivalences exists, it just a matter of combining data types.<br />
Of course, you could implement these as named maps/sets as well.<br />
<br />
<br />
'''hash:net,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,port,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . tcp dport . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 80 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,iface'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . iif vmap { 10.10.10.0 . eth0 : accept }<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Concatenations&diff=332Concatenations2018-08-14T08:05:04Z<p>Duncan: TCP & UDP are level 4 protocols, not 3</p>
<hr />
<div>Since Linux kernel 4.1, nftables supports concatenations.<br />
<br />
This new feature allows you to put two or more selectors together to perform very fast lookups by combining them with [[sets]], [[dictionaries]], [[maps]] and [[meters]].<br />
<br />
= Literal sets =<br />
<br />
<source lang="bash"><br />
% nft add rule ip filter input ip saddr . ip daddr . ip protocol { 1.1.1.1 . 2.2.2.2 . tcp, 1.1.1.1 . 3.3.3.3 . udp} counter accept<br />
</source><br />
<br />
So if the packet matches source IP address AND destination IP address AND level 4 protocol:<br />
<br />
* 1.1.1.1 and 2.2.2.2 and TCP.<br />
<br />
or<br />
<br />
* 1.1.1.1 and 3.3.3.3 and UDP.<br />
<br />
nftables updates the counter for this rule and then accepts the packet.<br />
<br />
= Dictionary declarations =<br />
<br />
The following example creates the ''whitelist'' dictionary using a concatenation of two selectors:<br />
<br />
<source lang="bash"><br />
% nft add map filter whitelist { type ipv4_addr . inet_service : verdict \; }<br />
</source><br />
<br />
Once you create the dictionary, you can use it from a rule that creates the following concatenation:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr . tcp dport vmap @whitelist<br />
</source><br />
<br />
Thus, the rule above looks up for a verdict based on the source IP address AND the TCP destination port.<br />
<br />
Since the dictionary is initially empty, you can dynamically populate this dictionary with elements through:<br />
<br />
<source lang="bash"><br />
% nft add element filter whitelist { 1.2.3.4 . 22 : accept}<br />
</source><br />
<br />
= Literal maps =<br />
<br />
The rule below determines the destination IP address that is used to perform DNAT to the packet based on:<br />
<br />
* the source IP address<br />
<br />
AND<br />
<br />
* the destination TCP port<br />
<br />
<source lang="bash"><br />
% nft add rule ip nat prerouting dnat ip saddr . tcp dport map { 1.1.1.1 . 80 : 192.168.1.100, 2.2.2.2 . 8888 : 192.168.1.101 }<br />
</source><br />
<br />
= Examples =<br />
<br />
Some concrete example concatenations so you get an idea on how powerful this new feature is.<br />
<br />
== Network addresses ==<br />
<br />
The example below implements a dictionary using network masks as matching element.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
Note that this is not an interval, this is masking the ip saddr and ip daddr, then concate both results. This concatenation is used to lookup for a matching of this the result in the map. This syntax may be compacted in future releases to support CIDR notation.<br />
<br />
This could be easily implemented using a named map as well:<br />
<br />
<source lang="bash"><br />
% nft add map tablename myMap { type ipv4_addr . ipv4_addr : verdict \; }<br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip saddr and 255.255.255.0 vmap @myMap<br />
% nft add element tablename myMap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
== Interfaces ==<br />
<br />
The example below checks both input and output interfaces of a forwarded packet.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname iif . oif vmap { eth0 . eth1 : accept }<br />
</source><br />
<br />
Please note that using strings (for example iifname and oifname) and other variable sized data types is not supported yet.<br />
<br />
== Some ipset types ==<br />
<br />
These ipset types can be implemented in nftables using concatenations. Probably more equivalences exists, it just a matter of combining data types.<br />
Of course, you could implement these as named maps/sets as well.<br />
<br />
<br />
'''hash:net,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,port,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . tcp dport . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 80 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,iface'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . iif vmap { 10.10.10.0 . eth0 : accept }<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Concatenations&diff=331Concatenations2018-08-14T00:55:42Z<p>Duncan: There is nothing to do with ports here. We are matching on protocol only</p>
<hr />
<div>Since Linux kernel 4.1, nftables supports concatenations.<br />
<br />
This new feature allows you to put two or more selectors together to perform very fast lookups by combining them with [[sets]], [[dictionaries]], [[maps]] and [[meters]].<br />
<br />
= Literal sets =<br />
<br />
<source lang="bash"><br />
% nft add rule ip filter input ip saddr . ip daddr . ip protocol { 1.1.1.1 . 2.2.2.2 . tcp, 1.1.1.1 . 3.3.3.3 . udp} counter accept<br />
</source><br />
<br />
So if the packet is source IP address AND destination IP address AND level 3 protocol match:<br />
<br />
* 1.1.1.1 and 2.2.2.2 and TCP.<br />
<br />
or<br />
<br />
* 1.1.1.1 and 3.3.3.3 and UDP.<br />
<br />
nftables updates the counter for this rule and then accepts the packet.<br />
<br />
= Dictionary declarations =<br />
<br />
The following example creates the ''whitelist'' dictionary using a concatenation of two selectors:<br />
<br />
<source lang="bash"><br />
% nft add map filter whitelist { type ipv4_addr . inet_service : verdict \; }<br />
</source><br />
<br />
Once you create the dictionary, you can use it from a rule that creates the following concatenation:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr . tcp dport vmap @whitelist<br />
</source><br />
<br />
Thus, the rule above looks up for a verdict based on the source IP address AND the TCP destination port.<br />
<br />
Since the dictionary is initially empty, you can dynamically populate this dictionary with elements through:<br />
<br />
<source lang="bash"><br />
% nft add element filter whitelist { 1.2.3.4 . 22 : accept}<br />
</source><br />
<br />
= Literal maps =<br />
<br />
The rule below determines the destination IP address that is used to perform DNAT to the packet based on:<br />
<br />
* the source IP address<br />
<br />
AND<br />
<br />
* the destination TCP port<br />
<br />
<source lang="bash"><br />
% nft add rule ip nat prerouting dnat ip saddr . tcp dport map { 1.1.1.1 . 80 : 192.168.1.100, 2.2.2.2 . 8888 : 192.168.1.101 }<br />
</source><br />
<br />
= Examples =<br />
<br />
Some concrete example concatenations so you get an idea on how powerful this new feature is.<br />
<br />
== Network addresses ==<br />
<br />
The example below implements a dictionary using network masks as matching element.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
Note that this is not an interval, this is masking the ip saddr and ip daddr, then concate both results. This concatenation is used to lookup for a matching of this the result in the map. This syntax may be compacted in future releases to support CIDR notation.<br />
<br />
This could be easily implemented using a named map as well:<br />
<br />
<source lang="bash"><br />
% nft add map tablename myMap { type ipv4_addr . ipv4_addr : verdict \; }<br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip saddr and 255.255.255.0 vmap @myMap<br />
% nft add element tablename myMap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
== Interfaces ==<br />
<br />
The example below checks both input and output interfaces of a forwarded packet.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname iif . oif vmap { eth0 . eth1 : accept }<br />
</source><br />
<br />
Please note that using strings (for example iifname and oifname) and other variable sized data types is not supported yet.<br />
<br />
== Some ipset types ==<br />
<br />
These ipset types can be implemented in nftables using concatenations. Probably more equivalences exists, it just a matter of combining data types.<br />
Of course, you could implement these as named maps/sets as well.<br />
<br />
<br />
'''hash:net,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,port,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . tcp dport . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 80 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,iface'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . iif vmap { 10.10.10.0 . eth0 : accept }<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Concatenations&diff=316Concatenations2018-05-01T05:07:45Z<p>Duncan: Add meters to the list of items where you can use concatenations</p>
<hr />
<div>Since Linux kernel 4.1, nftables supports concatenations.<br />
<br />
This new feature allows you to put two or more selectors together to perform very fast lookups by combining them with [[sets]], [[dictionaries]], [[maps]] and [[meters]].<br />
<br />
= Literal sets =<br />
<br />
<source lang="bash"><br />
% nft add rule ip filter input ip saddr . ip daddr . ip protocol { 1.1.1.1 . 2.2.2.2 . tcp, 1.1.1.1 . 3.3.3.3 . udp} counter accept<br />
</source><br />
<br />
So if the packet is source IP address AND destination IP address AND TCP destination port match:<br />
<br />
* 1.1.1.1 and 2.2.2.2 and TCP.<br />
<br />
or<br />
<br />
* 1.1.1.1 and 3.3.3.3 and UDP.<br />
<br />
nftables updates the counter for this rule and then accepts the packet.<br />
<br />
= Dictionary declarations =<br />
<br />
The following example creates the ''whitelist'' dictionary using a concatenation of two selectors:<br />
<br />
<source lang="bash"><br />
% nft add map filter whitelist { type ipv4_addr . inet_service : verdict \; }<br />
</source><br />
<br />
Once you create the dictionary, you can use it from a rule that creates the following concatenation:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr . tcp dport vmap @whitelist<br />
</source><br />
<br />
Thus, the rule above looks up for a verdict based on the source IP address AND the TCP destination port.<br />
<br />
Since the dictionary is initially empty, you can dynamically populate this dictionary with elements through:<br />
<br />
<source lang="bash"><br />
% nft add element filter whitelist { 1.2.3.4 . 22 : accept}<br />
</source><br />
<br />
= Literal maps =<br />
<br />
The rule below determines the destination IP address that is used to perform DNAT to the packet based on:<br />
<br />
* the source IP address<br />
<br />
AND<br />
<br />
* the destination TCP port<br />
<br />
<source lang="bash"><br />
% nft add rule ip nat prerouting dnat ip saddr . tcp dport map { 1.1.1.1 . 80 : 192.168.1.100, 2.2.2.2 . 8888 : 192.168.1.101 }<br />
</source><br />
<br />
= Examples =<br />
<br />
Some concrete example concatenations so you get an idea on how powerful this new feature is.<br />
<br />
== Network addresses ==<br />
<br />
The example below implements a dictionary using network masks as matching element.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
Note that this is not an interval, this is masking the ip saddr and ip daddr, then concate both results. This concatenation is used to lookup for a matching of this the result in the map. This syntax may be compacted in future releases to support CIDR notation.<br />
<br />
This could be easily implemented using a named map as well:<br />
<br />
<source lang="bash"><br />
% nft add map tablename myMap { type ipv4_addr . ipv4_addr : verdict \; }<br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip saddr and 255.255.255.0 vmap @myMap<br />
% nft add element tablename myMap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
== Interfaces ==<br />
<br />
The example below checks both input and output interfaces of a forwarded packet.<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname iif . oif vmap { eth0 . eth1 : accept }<br />
</source><br />
<br />
Please note that using strings (for example iifname and oifname) and other variable sized data types is not supported yet.<br />
<br />
== Some ipset types ==<br />
<br />
These ipset types can be implemented in nftables using concatenations. Probably more equivalences exists, it just a matter of combining data types.<br />
Of course, you could implement these as named maps/sets as well.<br />
<br />
<br />
'''hash:net,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,port,net'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . tcp dport . ip daddr and 255.255.255.0 vmap { 10.10.10.0 . 80 . 10.10.20.0 : accept }<br />
</source><br />
<br />
'''hash:net,iface'''<br />
<br />
<source lang="bash"><br />
% nft add rule tablename chainname ip saddr and 255.255.255.0 . iif vmap { 10.10.10.0 . eth0 : accept }<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=308Meters2018-04-15T08:23:11Z<p>Duncan: (grammer)</p>
<hr />
<div>== Meters ==<br />
<br />
This feature used to be known as ''flow tables'' before nft v0.8.1.<br />
<br />
Since Linux Kernel 4.3 and nft v0.8.1 nftables supports this feature.<br />
<br />
Meters provide a native replacement for the ''hashlimit'' match in iptables, however, meters are a lot more flexible since you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using meters ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a meter:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new meter ssh-meter { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a meter named ''ssh-meter'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
Note that a meter must have a name, so you can list its content.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input meter cnt-meter { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing meters ==<br />
<br />
To list the content matched by the meter use:<br />
<br />
<source lang="bash"><br />
% nft list meter filter cnt-meter<br />
table ip filter {<br />
meter cnt-meter {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Meters replace iptables hashlimit in nft. From iptables v1.6.2 onward, you can use the tool '''iptables-translate''' to see how to translate hashlimit rules.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a meter. All modes are available except no mode, a meter demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http1 { tcp dport . ip saddr limit rate over 200/second } counter drop<br />
</source><br />
<br />
Notice that a meter is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a meter:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a meter, also notice that meters, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a meter selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http3 { ip saddr and 255.255.255.0 limit rate 200/second } counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to meters.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=307Meters2018-04-15T08:18:22Z<p>Duncan: No longer need to get iptables from the git tree for hashlimit translate support</p>
<hr />
<div>== Meters ==<br />
<br />
This feature used to be known as ''flow tables'' before nft v0.8.1.<br />
<br />
Since Linux Kernel 4.3 and nft v0.8.1 nftables supports this feature.<br />
<br />
Meters provide a native replacement for the ''hashlimit'' match in iptables, however, meters are a lot more flexible since you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using meters ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a meter:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new meter ssh-meter { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a meter named ''ssh-meter'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
Note that meters must have a name, so you can list its content.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input meter cnt-meter { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing meters ==<br />
<br />
To list the content matched by the meter use:<br />
<br />
<source lang="bash"><br />
% nft list meter filter cnt-meter<br />
table ip filter {<br />
meter cnt-meter {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Meters replace iptables hashlimit in nft. From iptables v1.6.2 onward, you can use the tool '''iptables-translate''' to see how to translate hashlimit rules.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a meter. All modes are available except no mode, a meter demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http1 { tcp dport . ip saddr limit rate over 200/second } counter drop<br />
</source><br />
<br />
Notice that a meter is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a meter:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a meter, also notice that meters, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a meter selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http3 { ip saddr and 255.255.255.0 limit rate 200/second } counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to meters.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=306Meters2018-04-15T08:03:10Z<p>Duncan: Sample meter is called ssh-meter (not metering)</p>
<hr />
<div>== Meters ==<br />
<br />
This feature used to be known as ''flow tables'' before nft v0.8.1.<br />
<br />
Since Linux Kernel 4.3 and nft v0.8.1 nftables supports this feature.<br />
<br />
Meters provide a native replacement for the ''hashlimit'' match in iptables, however, meters are a lot more flexible since you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using meters ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a meter:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new meter ssh-meter { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a meter named ''ssh-meter'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
Note that meters must have a name, so you can list its content.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input meter cnt-meter { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing meters ==<br />
<br />
To list the content matched by the meter use:<br />
<br />
<source lang="bash"><br />
% nft list meter filter cnt-meter<br />
table ip filter {<br />
meter cnt-meter {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Meters replace iptables hashlimit in nft. You can use the tool '''iptables-translate''' to see how to translate hashlimit rules, currently available in the [https://git.netfilter.org/iptables/ iptables git tree] and expected in the next official release, current release is v1.6.1.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a meter. All modes are available except no mode, a meter demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http1 { tcp dport . ip saddr limit rate over 200/second } counter drop<br />
</source><br />
<br />
Notice that a meter is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a meter:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a meter, also notice that meters, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a meter selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 meter http3 { ip saddr and 255.255.255.0 limit rate 200/second } counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to meters.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Rate_limiting_matchings&diff=305Rate limiting matchings2018-04-07T00:05:09Z<p>Duncan: Add an example of the ''over'' keyword</p>
<hr />
<div>You can ratelimit traffic through ''limit''.<br />
<br />
The following example shows how to accept a maximum of 10 ICMP echo-request packets per second:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request limit rate 10/second accept<br />
</source><br />
<br />
Since Linux kernel 4.3, you can also ratelimit per bytes:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input limit rate 10 mbytes/second accept<br />
</source><br />
<br />
The rule above accepts traffic below the 10 mbytes/seconds rate.<br />
<br />
You can also use the ''burst'' parameter to indicate the number of packets/bytes you can exceed the ratelimit:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input limit rate 10 mbytes/second burst 9000 kbytes accept<br />
</source><br />
<br />
This indicates that you can exceed the ratelimit in 9000 kbytes.<br />
<br />
You can also use it for packets:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request limit rate 10/second burst 2 packets counter accept<br />
</source><br />
<br />
So you can exceed the rate in 2 packets.<br />
<br />
You can also use the ''limit'' expression for traffic policing in a rule using the ''ingress'' hook in the new ''netdev'' family (instead of using the ''tc'' command).<br />
<br />
The ''over'' keyword allows you to use ''limit'' intuitively in a chain with ''policy accept'':<br />
<source lang="bash"><br />
% nft add rule netdev filter ingress pkttype broadcast limit rate over 10/second drop<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Rate_limiting_matchings&diff=304Rate limiting matchings2018-04-06T23:35:04Z<p>Duncan: Re-work ingress line for clarity</p>
<hr />
<div>You can ratelimit traffic through ''limit''.<br />
<br />
The following example shows how to accept a maximum of 10 ICMP echo-request packets per second:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request limit rate 10/second accept<br />
</source><br />
<br />
Since Linux kernel 4.3, you can also ratelimit per bytes:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input limit rate 10 mbytes/second accept<br />
</source><br />
<br />
The rule above accepts traffic below the 10 mbytes/seconds rate.<br />
<br />
You can also use the ''burst'' parameter to indicate the number of packets/bytes you can exceed the ratelimit:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input limit rate 10 mbytes/second burst 9000 kbytes accept<br />
</source><br />
<br />
This indicates that you can exceed the ratelimit in 9000 kbytes.<br />
<br />
You can also use it for packets:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request limit rate 10/second burst 2 packets counter accept<br />
</source><br />
<br />
So you can exceed the rate in 2 packets.<br />
<br />
You can also use the ''limit'' expression for traffic policing in a rule using the ''ingress'' hook in the new ''netdev'' family (instead of using the ''tc'' command).</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Main_Page&diff=279Main Page2018-02-03T07:18:27Z<p>Duncan: Add video of LCA2018 talk</p>
<hr />
<div>Welcome to the ''nftables'' HOWTO documentation page. Here you will find documentation on how to build, install, configure and use nftables.<br />
<br />
If you have any suggestion to improve it, please send your comments to Netfilter users mailing list <netfilter@vger.kernel.org>.<br />
<br />
= Introduction =<br />
<br />
* [[What is nftables?]]<br />
* [[Why nftables?]]<br />
* [[Main differences with iptables]]<br />
* [[Netfilter hooks]] and integration with existing Netfilter components.<br />
<br />
= Getting started =<br />
<br />
* [[Building and installing nftables from sources]]<br />
* Using [[nftables from distributions]]<br />
* [[Troubleshooting|Troubleshooting and FAQ]]<br />
* [[Quick reference-nftables in 10 minutes|Quick reference, nftables in 10 minutes]]<br />
* [[nftables families|Understanding nftables families]]<br />
<br />
= Basic operation =<br />
<br />
* [[Configuring tables]]<br />
* [[Configuring chains]]<br />
* [[Simple rule management]]<br />
* [[Atomic rule replacement]]<br />
* [[Error reporting from the command line]]<br />
* [[Building rules through expressions]]<br />
* [[Operations at ruleset level]]<br />
* [[Monitoring ruleset updates]]<br />
* [[Scripting]]<br />
* [[Ruleset debug/tracing]]<br />
* [[Moving from iptables to nftables]]<br />
* [[Moving from ipset to nftables]]<br />
<br />
= Supported selectors for packet matching =<br />
<br />
* [[Matching packet header fields]]<br />
* [[Matching packet metainformation]]<br />
* [[Matching connection tracking stateful metainformation]]<br />
* [[Rate limiting matchings]]<br />
* [[Routing information]]<br />
<br />
= Possible actions on packets =<br />
<br />
* [[Accepting and dropping packets]]<br />
* [[Jumping to chain]]<br />
* [[Rejecting traffic]]<br />
* [[Logging traffic]]<br />
* [[Performing Network Address Translation (NAT)]]<br />
* [[Setting packet metainformation]]<br />
* [[Queueing to userspace]]<br />
* [[Duplicating packets]]<br />
* [[Mangle packet header fields]]<br />
* [[Mangle TCP options]]<br />
* [[Counters]]<br />
* [[Load balancing]]<br />
* [[Setting packet connection tracking metainformation]]<br />
<br />
Note that, unlike ''iptables'', you can perform several actions in one single rule.<br />
<br />
= Advanced data structures for performance packet classification =<br />
<br />
You will have to redesign your rule-set to benefit from these new nice features:<br />
<br />
* [[Sets]]<br />
* [[Dictionaries]]<br />
* [[Intervals]]<br />
* [[Maps]]<br />
* [[Concatenations]]<br />
* [[Meters|Metering]] (formerly known as flow tables before nftables 0.8.1 release)<br />
* [[Updating sets from the packet path]]<br />
* [[Element timeouts]]<br />
* [[Math operations]]<br />
* [[Stateful objects]]<br />
<br />
If you are already using [[ipset]] in your ''iptables'' rule-set, that transition may be a bit more simple to you.<br />
<br />
= Examples =<br />
<br />
* [[Simple ruleset for a workstation]]<br />
* [[Bridge filtering]]<br />
* [[Multiple NATs using nftables maps]]<br />
* [[Classic perimetral firewall example]]<br />
<br />
= Development progress =<br />
<br />
* [[List of updates since Linux kernel 3.13]]<br />
* [[Supported features compared to xtables|Supported features compared to {ip,ip6,eb,arp}tables]]<br />
* [[List of available translations via iptables-translate tool]]<br />
<br />
= External links =<br />
<br />
Watch some videos:<br />
<br />
* Watch [https://www.youtube.com/watch?v=FXTRRwXi3b4 Getting a grasp of nftables], thanks to [https://www.nluug.nl/index-en.html NLUUG association] for recording this.<br />
* Watch [https://www.youtube.com/watch?v=CaYp0d2wiuU#t=1m47s The ultimate packet classifier for GNU/Linux], thanks to the FSFE for paying my trip to Barcelona and for recommending me as speaker to the KDE Spanish branch.<br />
* [https://www.youtube.com/watch?v=Sy0JDX451ns Florian Westphal - Why nftables?]<br />
* Watch [https://www.youtube.com/watch?v=qXVOA2MKA1s Netdev 2.1 - Netfilter workshop]<br />
* Watch [https://www.youtube.com/watch?v=0wQfSfDVN94 NLUUG - Goodbye iptables, Hello nftables]<br />
* Watch [https://www.youtube.com/watch?v=Uf5ULkEWPL0 LCA2018 - nftables from a user perspective]<br />
<br />
Additional documentations and articles:<br />
<br />
* Tutorial [https://zasdfgbnm.github.io/2017/09/07/Extending-nftables/ Extending nftables by Xiang Gao]<br />
* Article [http://ral-arturo.org/2017/05/05/debian-stretch-stable-nftables.html New in Debian stable Stretch: nftables]<br />
<br />
= Thanks =<br />
<br />
To the NLnet foundation for initial sponsorship of this HOWTO:<br />
<br />
[https://nlnet.nl https://nlnet.nl/image/logo.gif]<br />
<br />
To Eric Leblond, for boostrapping the [https://home.regit.org/netfilter-en/nftables-quick-howto/ Nftables quick howto] in 2013.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=235Meters2018-01-15T01:16:38Z<p>Duncan: The examples now work as originally documented</p>
<hr />
<div>== Flow tables ==<br />
<br />
Since Linux Kernel 4.3 and nft v0.6 nftables supports flow tables.<br />
<br />
Flow tables provides a native replacement for the ''hashlimit'' match in iptables, however, you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using flow tables ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a flow table:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new flow table ssh-ftable { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a flow table named ''ssh-ftable'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input flow table cnt-ftable { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing flow tables ==<br />
<br />
To list the content matched by the flow table use:<br />
<br />
<source lang="bash"><br />
% nft list flow table filter cnt-ftable<br />
table ip filter {<br />
flow table cnt-ftable {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Flow tables replace iptables hashlimit in nft. You can use the tool '''iptables-translate''' to see how to translate hashlimit rules, currently available in the [https://git.netfilter.org/iptables/ iptables git tree] and expected in the next official release, current release is v1.6.1.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a flow table. All modes are available except no mode, a flow table demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http1 { tcp dport . ip saddr limit rate over 200/second } counter drop<br />
</source><br />
<br />
Notice that a flow table is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a flow table:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a flow table, also notice that flow tables, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a flow table selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http3 { ip saddr and 255.255.255.0 limit rate 200/second } counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to flow tables.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=230Meters2017-12-17T00:24:24Z<p>Duncan: 1000 is 1000 milliseconds</p>
<hr />
<div>== Flow tables ==<br />
<br />
Since Linux Kernel 4.3 and nft v0.6 nftables supports flow tables.<br />
<br />
Flow tables provides a native replacement for the ''hashlimit'' match in iptables, however, you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using flow tables ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a flow table:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new flow table ssh-ftable { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a flow table named ''ssh-ftable'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input flow table cnt-ftable { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing flow tables ==<br />
<br />
To list the content matched by the flow table use:<br />
<br />
<source lang="bash"><br />
% nft list flow table filter cnt-ftable<br />
table ip filter {<br />
flow table cnt-ftable {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Flow tables replace iptables hashlimit in nft. You can use the tool '''iptables-translate''' to see how to translate hashlimit rules, currently available in the [https://git.netfilter.org/iptables/ iptables git tree] and expected in the next official release, current release is v1.6.1.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a flow table. All modes are available except no mode, a flow table demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http1 { tcp dport . ip saddr timeout 1s limit rate over 200/second burst 5 packets} counter drop<br />
</source><br />
<br />
Notice that a flow table is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
Notice also that the translator defaults --hashlimit-htable-expire and --hashlimit-burst to 1000 milliseconds and 5 packets respectively so ''timeout 1s'' and ''burst 5 packets'' are inserted. You may remove either or both of these if you wish.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a flow table:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a flow table, also notice that flow tables, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a flow table selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http3 { ip saddr and 255.255.255.0 timeout 1s limit rate 200/second burst 5 packets} counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to flow tables.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=User:Duncan&diff=229User:Duncan2017-12-16T08:40:15Z<p>Duncan: Created page with "email duncan underscore roe at optusnet dot com dot au"</p>
<hr />
<div>email duncan underscore roe at optusnet dot com dot au</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Talk:Meters&diff=228Talk:Meters2017-12-16T08:38:07Z<p>Duncan: explain today's changes a bit more</p>
<hr />
<div>The page was showing iptables & nft commands issued from the dollar (non-root) prompt when they only work from root. So I changed iptables to iptables-translate (which does work from the dollar prompt) and converted the nft command to being the output from iptables-translate.<br />
<br />
From actually trying the examples, I found iptables-translate was always inserting timeout and burst sub-commands. I don't know whether that is deliberate but documented it because that's what happens. I put in the note that you can miss them out because the original nft commands didn't have them. Can someone ack that it makes sense to miss them out please.<br />
<br />
The page doesn't flow quite so well now because burst and timeout are mentioned before they are described. If you have any suggestion how this could be improved you can email them to me or implement them yourself.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Meters&diff=227Meters2017-12-16T07:56:35Z<p>Duncan: Show iptables-translate commands;show actual output including inserted "timeout 1s"; add a note about this insertion</p>
<hr />
<div>== Flow tables ==<br />
<br />
Since Linux Kernel 4.3 and nft v0.6 nftables supports flow tables.<br />
<br />
Flow tables provides a native replacement for the ''hashlimit'' match in iptables, however, you can use any selector, one or many through [[concatenations]].<br />
<br />
== Using flow tables ==<br />
<br />
The following commands create a table named ''filter'', a chain named ''input'' which hooks incoming traffic and a rule that uses a flow table:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add chain filter input {type filter hook input priority 0\;}<br />
% nft add rule filter input tcp dport 22 ct state new flow table ssh-ftable { ip saddr limit rate 10/second } accept<br />
</source><br />
<br />
In this example we create a rule to match ''new'' ''ssh'' (port 22) connections, which uses a flow table named ''ssh-ftable'' to limit the traffic rate to 10 packets per second for each source IP address. The available time units on limits are: ''second'', ''minute'', ''hour'', ''day'' and ''week''.<br />
<br />
You can also use [[concatenations]] to build selectors:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input flow table cnt-ftable { iif . ip saddr . tcp dport timeout 60s counter }<br />
</source><br />
<br />
This rule counts incoming packets based on the tuple ''(input interface index, IP source address, TCP destination port)'', the counters are dropped after 60 seconds without update.<br />
<br />
== Listing flow tables ==<br />
<br />
To list the content matched by the flow table use:<br />
<br />
<source lang="bash"><br />
% nft list flow table filter cnt-ftable<br />
table ip filter {<br />
flow table cnt-ftable {<br />
type iface_index . ipv4_addr . inet_service<br />
flags timeout<br />
elements = { "wlan1" . 64.62.190.36 . 55000 expires 38s : counter packets 2 bytes 220, "wlan1" . 83.98.201.47 . 35460 expires 39s : counter packets 10 bytes 5988, "wlan1" . 172.217.7.142 . 43254 expires 46s : counter packets 1 bytes 98}<br />
}<br />
}<br />
</source><br />
<br />
== Doing iptables hashlimit with nft ==<br />
<br />
Flow tables replace iptables hashlimit in nft. You can use the tool '''iptables-translate''' to see how to translate hashlimit rules, currently available in the [https://git.netfilter.org/iptables/ iptables git tree] and expected in the next official release, current release is v1.6.1.<br />
<br />
Almost all hashlimit options are available in nft, starting with --hashlimit-mode, it is replaced by the selector in a flow table. All modes are available except no mode, a flow table demands a selector, an iptables rule without hashlimit-mode isn't supported in nft. A simple rule translation is:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200/sec --hashlimit-mode srcip,dstport --hashlimit-name http1 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http1 { tcp dport . ip saddr timeout 1s limit rate over 200/second burst 5 packets} counter drop<br />
</source><br />
<br />
Notice that a flow table is named, like hashlimit, and using multiple hashlimit-modes is similar to using a concatenation of selectors. Also, --hashlimit-above is translated to ''limit rate over'', to simulate --hashlimit-upto just omit or replace ''over'' with ''until'' in the rule.<br />
Notice also that the translator defaults --hashlimit-htable-expire and --hashlimit-burst to 1000 and 5 packets respectively so ''timeout 1s'' and ''burst 5 packets'' are inserted. You may remove either or both of these if you wish.<br />
<br />
The options --hashlimit-burst and --hashlimit-htable-expire are translated to ''burst'' and ''timeout'' in a flow table:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-above 200kb/s --hashlimit-burst 1mb --hashlimit-mode srcip,dstport --hashlimit-name http2 --hashlimit-htable-expire 3000 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http2 { tcp dport . ip saddr timeout 3s limit rate over 200 kbytes/second burst 1 mbytes} counter drop<br />
</source><br />
<br />
This rule shows how ''timeout'' and ''burst'' are used in a flow table, also notice that flow tables, similarly to hashlimit, accepts limiting rates by bytes frequency instead of packets.<br />
<br />
Another hashlimit option is to limit the traffic rate on subnets, of IP source or destination addresses, using the options --hashlimit-srcmask and --hashlimit-dstmask. This feature is available in nft by attaching a subnet mask to a flow table selector, attach to ''ip saddr'' for source address and to ''ip daddr'' for destination adress:<br />
<br />
<source lang="bash"><br />
$ iptables-translate -A INPUT -m tcp -p tcp --dport 80 -m hashlimit --hashlimit-upto 200 --hashlimit-mode srcip --hashlimit-name http3 --hashlimit-srcmask 24 -j DROP<br />
nft add rule ip filter INPUT tcp dport 80 flow table http3 { ip saddr and 255.255.255.0 timeout 1s limit rate 200/second burst 5 packets} counter drop<br />
</source><br />
<br />
This rule will limit packets rate, grouping subnets determined by the first 24 bits of the IP source address, from the incoming packets on port 80.<br />
<br />
The remaining options, --hashlimit-htable-max, --hashlimit-htable-size and --hashlimit-htable-gcinterval don't apply to flow tables.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Stateful_objects&diff=210Stateful objects2017-12-05T01:37:29Z<p>Duncan: Fix spelling of reseting to resetting</p>
<hr />
<div>Since Linux Kernel 4.10 and nft v0.8 nftables supports stateful objects.<br />
<br />
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.<br />
<br />
= Creating stateful objects =<br />
<br />
You can create a counter with the command:<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add counter filter https-traffic<br />
</source><br />
<br />
These rules create a table named ''filter'', then a counter named ''https-traffic'' and attaches it to ''filter''.<br />
<br />
Creating a quota is similar:<br />
<br />
<source lang="bash"><br />
% nft add quota filter https-quota 25 mbytes<br />
</source><br />
<br />
A quota named ''https-quota'' is attached to the table ''filter'', notice that you must specify the quota's size on creation.<br />
<br />
= Referencing stateful objects in rules =<br />
<br />
Stateful objects are referenced in rules by their names, the simplest way is:<br />
<br />
<source lang="bash"><br />
% nft add chain filter output { type filter hook output priority 0 \; }<br />
% nft add rule filter output tcp dport https counter name https-traffic<br />
</source><br />
<br />
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''.<br />
<br />
They can also be used with maps:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output counter name tcp dport map { \<br />
https : "https-traffic", \<br />
80 : "http-traffic", \<br />
25 : "foo-counter", \<br />
50 : "foo-counter", \<br />
107 : "foo-counter" \<br />
}<br />
</source><br />
<br />
Similarly, dynamic maps can be used:<br />
<br />
<source lang="bash"><br />
% nft add map filter ports { type inet_service : quota \; }<br />
% nft add rule filter output quota name tcp dport map @ports<br />
% nft add quota filter http-quota over 25 mbytes<br />
% nft add quota filter ssh-quota 10 kbytes<br />
% nft add element filter ports { 80 : "http-quota" }<br />
% nft add element filter ports { 22 : "ssh-quota" }<br />
</source><br />
<br />
= Listing stateful objects =<br />
<br />
You can list the stateful information of objects individually via:<br />
<br />
<source lang="bash"><br />
% nft list counter filter https-traffic<br />
</source><br />
<br />
Also, it's possible to list all stateful objects of the same type:<br />
<br />
<source lang="bash"><br />
% nft list quotas<br />
</source><br />
<br />
And list all stateful objects of a type in a table:<br />
<br />
<source lang="bash"><br />
% nft list counters table filter<br />
</source><br />
<br />
= Resetting stateful objects =<br />
<br />
Resetting an object will atomically dump and reset its content:<br />
<br />
<source lang="bash"><br />
% nft reset quota filter https-quota<br />
table ip filter {<br />
quota https-quota {<br />
25 mbytes used 217 kbytes<br />
}<br />
}<br />
<br />
% nft list quota filter https-quota<br />
table ip filter {<br />
quota https-quota {<br />
25 mbytes<br />
}<br />
}<br />
</source><br />
<br />
Other usages are similar to the command list, e.g.<br />
<br />
<source lang="bash"><br />
% nft reset counters<br />
% nft reset quotas table filter<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Logging_traffic&diff=209Logging traffic2017-11-26T22:52:14Z<p>Duncan: It's just "level" to introduce syslog level</p>
<hr />
<div>'''Note''': Full logging support is available starting Linux kernel 3.17. If you run an older kernel, you have to modprobe ipt_LOG to enable logging.<br />
<br />
You can log packets using the ''log'' action. The most simple rule to log all incoming traffic is:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input log<br />
</source><br />
<br />
A typical rule match, log and accept incoming ''ssh'' traffic looks like:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 22 ct state new log prefix \"New SSH connection: \" accept<br />
</source><br />
<br />
The prefix indicates the initial string that is used as prefix for the log message.<br />
<br />
Note that nftables allows to perform two actions in one single rule, contrary to ''iptables'' which required two rules for this.<br />
<br />
Also note that the rule is evaluated from the left to the right. So the following rule:<br />
<source lang="bash"><br />
nft add rule filter input iif lo log tcp dport 22 accept<br />
</source><br />
will log all packets coming on lo interface and not only the ones with destination port 22.<br />
<br />
= Queueing logging to userspace =<br />
<br />
As in iptables, you can use the existing ''nflog'' infrastructure to send log messages to [http://www.netfilter.org/projects/ulogd2/ ulogd2] or your custom userspace application based on [http://www.netfilter.org/projects/libnetfilter_log/ libnetfilter_log].<br />
<br />
To do so, you only have to indicate the ''nflog'' group:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 22 ct state new log prefix \"New SSH connection: \" group 0 accept<br />
</source><br />
<br />
Then, run the example test application:<br />
<br />
<source lang="bash"><br />
libnetfilter_log/utils% ./nfulnl_test<br />
</source><br />
<br />
And you'll start seeing log messages for each new ''ssh'' connection.<br />
<br />
= Log flags =<br />
<br />
Since nftables v0.7, log flags are supported.<br />
<br />
Enable logging of TCP sequence and options:<br />
<br />
<source><br />
% nft add rule x y log flags tcp sequence,options<br />
</source><br />
<br />
Enable IP options:<br />
<br />
<source><br />
% nft add rule x y log flags ip options<br />
</source><br />
<br />
Enable socket UID:<br />
<br />
<source><br />
% nft add rule x y log flags skuid<br />
</source><br />
<br />
Enable ethernet link layer address:<br />
<br />
<source><br />
% nft add rule x y log flags ether<br />
</source><br />
<br />
Enable all flags:<br />
<br />
<source><br />
% nft add rule x y log flags all<br />
</source><br />
<br />
= Additional options =<br />
<br />
Some additional options exist to fine-tune logging in different scenarios:<br />
<br />
* '''level''': Syslog level of logging, a string of value: emerg, alert, crit, err, warn [default], notice, info, debug<br />
* '''snaplen''': Length of packet payload to include in netlink message (unsigned integer, 32 bit)<br />
* '''queue-threshold''': If queing logging to userspace, number of packets to queue inside the kernel before sending them to userspace (unsigned integer, 32 bit)<br />
<br />
In the example below, a queue-threshold parameter is used to increment ulogd2 daemon performance in userspace:<br />
<br />
<source><br />
% nft add rule filter forward ct state invalid log queue-threshold 20 prefix "ct_invalid" group 0 drop<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Configuring_chains&diff=208Configuring chains2017-11-21T22:07:08Z<p>Duncan: Change "package" to "packet"</p>
<hr />
<div>As in ''iptables'', you attach your [[Simple rule management|rules]] to chains. However, contrary to the ''iptables'' modus operandi, the ''nftables'' infrastructure comes with no predefined chains, so you need to register your base chains in first place before you can add any rule. This allows very flexible configurations.<br />
<br />
= Adding base chains =<br />
<br />
The syntax to add base chains is the following:<br />
<br />
<source lang="bash"><br />
% nft add chain [<family>] <table-name> <chain-name> { type <type> hook <hook> priority <value> \; [policy <policy>] } <br />
</source><br />
<br />
Base chains are those that are registered into the [[Netfilter hooks]], ie. these chains see packets flowing through your Linux TCP/IP stack.<br />
<br />
The following example show how you can add new base chains to the ''foo'' table through the following command:<br />
<br />
<source lang="bash"><br />
% nft add chain ip foo input { type filter hook input priority 0 \; } <br />
</source><br />
<br />
'''Important''': You have to escape the semicolon if you are running this command from ''bash''.<br />
<br />
This command registers the ''input'' chain, that it attached to the ''input'' hook so it will see packets that are addressed to the local processes.<br />
<br />
The ''priority'' is important since it determines the ordering of the chains, thus, if you have several chains in the ''input'' hook, you can decide which one sees packets before another.<br />
<br />
If you want to use ''nftables'' to filter traffic for desktop Linux computers, ie. a computer which does not forward traffic, you can also register the output chain:<br />
<br />
<source lang="bash"><br />
% nft add chain ip foo output { type filter hook output priority 0 \; } <br />
</source><br />
<br />
Now you are ready to filter incoming (directed to local processes) and outgoing (generated by local processes) traffic.<br />
<br />
'''Important note''': If you don't include the chain configuration that is specified enclosed in the curly braces, you are creating a non-base chain that will not see any packets (similar to ''iptables -N chain-name'').<br />
<br />
Since nftables 0.5, you can also specify the default policy for base chains as in ''iptables'':<br />
<br />
<source lang="bash"><br />
% nft add chain ip foo output { type filter hook output priority 0 \; policy accept\; } <br />
</source><br />
<br />
As in ''iptables'', the two possible default policies are ''accept'' and ''drop''.<br />
<br />
When adding a chain on '''ingress''' hook, it is mandatory to specify the device where the chain will be attached: <br />
<source lang="bash"><br />
% nft add chain netdev foo dev0filter { type filter hook ingress device eth0 priority 0 \; } <br />
</source><br />
<br />
== Base chain types ==<br />
<br />
The possible chain types are:<br />
<br />
* '''filter''', which is obviously used to filter packets. This is supported by the arp, bridge, ip, ip6 and inet table families.<br />
* '''route''', which is used to reroute packets if any relevant IP header field or the packet mark is modified. If you are familiar with ''iptables'', this chain type provides equivalent semantics to the ''mangle'' table but only for the ''output'' hook (for other hooks use type ''filter'' instead). This is supported by the ip and ip6 table families.<br />
* '''nat''', which is used to perform Networking Address Translation (NAT). The first packet that belongs to a flow always hits this chain, follow up packets not. Therefore, never use this chain for filtering. This is supported by the ip and ip6 table families.<br />
<br />
== Base chain hooks ==<br />
<br />
The possible hooks that you can use when you configure your chain are:<br />
<br />
* '''prerouting''': the routing decision for those packets didn't happen yet, so you don't know if they are addressed to the local or remote systems.<br />
* '''input''': It happens after the routing decision, you can see packets that are directed to the local system and processes running in system.<br />
* '''forward''': It also happens after the routing decision, you can see packet that are not directed to the local machine.<br />
* '''output''': to catch packets that are originated from processes in the local machine.<br />
* '''postrouting''': After the routing decision for packets leaving the local system.<br />
* '''ingress''' (only available at the ''netdev'' family): Since Linux kernel 4.2, you can filter traffic way before prerouting, after the packet is passed up from the NIC driver. So you have an alternative to ''tc''.<br />
<br />
== Base chain priority ==<br />
<br />
The priority can be used to order the chains or to put them before or after some Netfilter internal operations. For example, a chain on the ''prerouting'' hook with the priority ''-300'' will be placed before connection tracking operations. <br />
<br />
For reference, here's the list of different priority used in iptables:<br />
<br />
* NF_IP_PRI_CONNTRACK_DEFRAG (-400): priority of defragmentation<br />
* NF_IP_PRI_RAW (-300): traditional priority of the raw table placed before connection tracking operation<br />
* NF_IP_PRI_SELINUX_FIRST (-225): SELinux operations<br />
* NF_IP_PRI_CONNTRACK (-200): Connection tracking operations<br />
* NF_IP_PRI_MANGLE (-150): mangle operation<br />
* NF_IP_PRI_NAT_DST (-100): destination NAT<br />
* NF_IP_PRI_FILTER (0): filtering operation, the filter table<br />
* NF_IP_PRI_SECURITY (50): Place of security table where secmark can be set for example<br />
* NF_IP_PRI_NAT_SRC (100): source NAT<br />
* NF_IP_PRI_SELINUX_LAST (225): SELinux at packet exit<br />
* NF_IP_PRI_CONNTRACK_HELPER (300): connection tracking at exit<br />
<br />
<br />
'''NOTE''': if a packet gets accepted/dropped and there is a later chain in the same hook which is ordered with a later priority, the packet will be evaluated '''again'''.<br />
This is, the packet will traverse all the chains in a given hook.<br />
<br />
Example ruleset of this behavior:<br />
<br />
<pre><br />
table inet filter {<br />
# this chain is evaluated first due to priority<br />
chain ssh {<br />
type filter hook input priority 0; policy accept;<br />
# ssh packet accepted<br />
tcp dport ssh accept<br />
}<br />
<br />
# this chain is evaluated last due to priority<br />
chain input {<br />
type filter hook input priority 1; policy drop;<br />
# the same ssh packet is dropped here by means of default policy<br />
}<br />
}<br />
</pre><br />
<br />
== Base chain policy ==<br />
<br />
This is the default verdict that will be applied to packets reaching the end of the chain (i.e, no more rules to be evaluated against).<br />
Currently there are 2 policies: '''accept''' or '''drop'''.<br />
<br />
* The ''accept'' verdict means that the packet will keep traversing the network stack.<br />
* The ''drop'' verdict means that the packet is discarded when this hook traversal is ended if no other verdict is applied later on (for example, in a higher priority chain in the same hook).<br />
<br />
= Adding non-base chains =<br />
<br />
You can also create non-base chains as in ''iptables'' via:<br />
<br />
<source lang="bash"><br />
% nft add chain ip foo test<br />
</source><br />
<br />
Note that this chain does '''not''' see any traffic as it is not attached to any hook, but it can be very useful to arrange your rule-set in a tree of chains by using the [[jumping to chain|jump to chain]] action.<br />
<br />
= Deleting chains =<br />
<br />
You can delete the chains that you don't need, eg.<br />
<br />
<source lang="bash"><br />
% nft delete chain ip foo input<br />
</source><br />
<br />
The only condition is that the chain you want to delete needs to be empty, otherwise the kernel will tell you that such chain is in used.<br />
<br />
<source lang="bash"><br />
% nft delete chain ip foo input<br />
<cmdline>:1:1-28: Error: Could not delete chain: Device or resource busy<br />
delete chain ip foo input<br />
^^^^^^^^^^^^^^^^^^^^^^^^^<br />
</source><br />
<br />
You will have to [[Simple rule management|flush the ruleset]] in that chain before you can remove the chain.<br />
<br />
= Flushing chain =<br />
<br />
You can also flush the content of a chain. If you want to flush all the rule in the chain ''input'' of the ''foo'' table, you have to type:<br />
<br />
<source lang="bash"><br />
nft flush chain foo input<br />
</source><br />
<br />
= Example configuration: Filtering traffic for your standalone computer =<br />
<br />
You can create a table with two base chains to define rule to filter traffic coming to and leaving from your computer, asumming IPv4 connectivity:<br />
<br />
<source lang="bash"><br />
% nft add table ip filter<br />
% nft add chain ip filter input { type filter hook input priority 0 \; }<br />
% nft add chain ip filter output { type filter hook output priority 0 \; }<br />
</source><br />
<br />
Now, you can start attaching [[Simple rule management|rules]] to these two base chains. Note that you don't need the ''forward'' chain in this case since this example assumes that you're configuring nftables to filter traffic for a standalone computer that doesn't behave as router.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Sets&diff=202Sets2017-11-20T05:00:15Z<p>Duncan: (English grammar corrrection)</p>
<hr />
<div>''nftables'' comes with a built-in generic set infrastructure that allows you to use '''any''' supported selector to build sets. This infrastructure makes possible the representation of [[dictionaries]] and [[maps]].<br />
<br />
The set elements are internally represented using performance data structures such as hashtables and red-black trees.<br />
<br />
= Anonymous sets =<br />
<br />
Anonymous sets are those that are:<br />
<br />
* Bound to a rule, if the rule is removed, that set is released too.<br />
* They have no specific name, the kernel internally allocates an identifier.<br />
* They cannot be updated. So you cannot add and delete elements from it once it is bound to a rule.<br />
<br />
The following example shows how to create a simple set.<br />
<br />
<source lang="bash"><br />
% nft add rule filter output tcp dport { 22, 23 } counter<br />
</source><br />
<br />
This rule above catches all traffic going to TCP ports 22 and 23, in case of matching the counters are updated.<br />
<br />
= Named sets =<br />
<br />
You can create the named sets with the following command:<br />
<br />
<source lang="bash"><br />
% nft add set filter blackhole { type ipv4_addr\;}<br />
</source><br />
<br />
Note that ''blackhole'' is the name of the set in this case. The ''type'' option indicates the data type that this set stores, which is an IPv4 address in this case. Current maximum name length is 16 characters.<br />
<br />
<source lang="bash"><br />
% nft add element filter blackhole { 192.168.3.4 }<br />
% nft add element filter blackhole { 192.168.1.4, 192.168.1.5 }<br />
</source><br />
<br />
Then, you can use it from the rule:<br />
<br />
<source lang="bash"><br />
% nft add rule ip input ip saddr @blackhole drop<br />
</source><br />
<br />
Named sets can be updated anytime, so you can add and delete element from them.<br />
<br />
Eric Leblond in his [https://home.regit.org/2014/01/why-you-will-love-nftables/ Why you will love nftables] article shows a very simple example to compare iptables with nftables:<br />
<br />
<source lang="bash"><br />
ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT<br />
</source><br />
<br />
Which can be expressed in ''nftables'' with a couple of rules that provide a set:<br />
<br />
<source lang="bash"><br />
% nft add rule ip6 filter input tcp dport {telnet, http, https} accept<br />
% nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept<br />
</source><br />
<br />
= Named sets specifications =<br />
<br />
Sets specifications are:<br />
<br />
* '''type''', is obligatory and determines the data type of the set elements. Supported data types currently are:<br />
** ''ipv4_addr'': IPv4 address<br />
** ''ipv6_addr'': IPv6 address.<br />
** ''ether_addr'': Ethernet address.<br />
** ''inet_proto'': Inet protocol type.<br />
** ''inet_service'': Internet service (read tcp port for example)<br />
** ''mark'': Mark type.<br />
<br />
* '''timeout''', it determines how long an element stays in the set. The time string respects the format: ''"v<sub>1</sub>dv<sub>2</sub>hv<sub>3</sub>mv<sub>4</sub>s"'':<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add set filter ports {type inet_service \; timeout 3h45s \;}<br />
</source><br />
<br />
These commands create a table named ''filter'' and add a set named ''ports'' to it, where elements are deleted after 3 hours and 45 seconds of being added.<br />
<br />
* '''flags''', the available flags are:<br />
** ''constant'' - set content may not change while bound<br />
** ''interval'' - set contains intervals<br />
** ''timeout'' - elements can be added with a timeout<br />
<br />
Multiple flags should be separated by comma:<br />
<br />
<source lang="bash"><br />
% nft add set filter flags_set {type ipv4_addr\; flags constant, interval\;}<br />
</source><br />
<br />
* '''gc-interval''', stands for garbage collection interval, can only be used if ''timeout'' or ''flags timeout'' are active. The interval follows the same format of ''timeouts'' time string ''"v<sub>1</sub>dv<sub>2</sub>hv<sub>3</sub>mv<sub>4</sub>s"''.<br />
<br />
* '''elements''', initialize the set with some elements in it:<br />
<br />
<source lang="bash"><br />
% nft add set filter daddrs {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}<br />
</source><br />
<br />
This command creates a set name ''daddrs'' with elements ''192.168.1.1'', which stays in it for 10s, and ''192.168.1.2'', which stays for 30s.<br />
<br />
* '''size''', limits the maximum number of elements of the set. To create a set with maximum 2 elements type:<br />
<br />
<source lang="bash"><br />
% nft add set filter saddrs {type ipv4_addr \; size 2 \;}<br />
</source><br />
<br />
* '''policy''', determines set selection policy. Available values are:<br />
** ''performance'' [default]<br />
** ''memory''<br />
<br />
= Listing named sets =<br />
<br />
You can list the content of a named set via:<br />
<br />
<source lang="bash"><br />
% nft list set filter myset<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Scripting&diff=201Scripting2017-11-19T07:08:32Z<p>Duncan: Update all the other "#!" lines in line with the previous update</p>
<hr />
<div>Many people like to maintain their ruleset in shell scripts, this allows them to add comments and arrange rules in more human-friendly way. This is problematic though since shell scripts break atomicity when applying the ruleset, thus, the filtering policy is applied in an inconsistent way during the ruleset loading time.<br />
<br />
Fortunately, nftables provides a native scripting environment to address these concerns which basically allows you to include other ruleset files, define variables and add comments. You have to restore the content of this native script through the ''nft -f my-ruleset.file'' command.<br />
<br />
To create a nftables script, you have to add the following header to your script file:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
</source><br />
<br />
= Adding comments =<br />
<br />
You can add comments to your file using the '#' character. Everything after the '#' will be ignored.<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
<br />
#<br />
# table declaration<br />
#<br />
add table filter<br />
<br />
#<br />
# chain declaration<br />
#<br />
add chain filter input { type filter hook input priority 0; policy drop; }<br />
<br />
#<br />
# rule declaration<br />
#<br />
add rule filter input ct state established,related counter accept<br />
</source><br />
<br />
= Including files =<br />
<br />
The example below shows how to include other ruleset files:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
<br />
include "ipv4-nat.ruleset"<br />
include "ipv6-nat.ruleset"<br />
</source><br />
<br />
= Defining variables =<br />
<br />
You can use the ''define'' keyword to define variables, the following example shows a very simple ruleset to account the traffic that comes from 8.8.8.8 (the popular Google DNS server):<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
<br />
define google_dns = 8.8.8.8<br />
<br />
add table filter<br />
add chain filter input { type filter hook input priority 0; }<br />
add rule filter input ip saddr $google_dns counter<br />
</source><br />
<br />
You can also define a variable for sets:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
<br />
define ntp_servers = { 84.77.40.132, 176.31.53.99, 81.19.96.148, 138.100.62.8 }<br />
<br />
add table filter<br />
add chain filter input { type filter hook input priority 0; }<br />
add rule filter input ip saddr $ntp_servers counter<br />
</source><br />
<br />
Don't forget that brackets have special semantics when used from rules, since they indicate that this variable represents a set. Therefore, avoid things like:<br />
<br />
<source lang="bash"><br />
define google_dns = { 8.8.8.8 }<br />
</source><br />
<br />
It is simply overkill to define a set that only stores one single element, instead use the singleton definition:<br />
<br />
<source lang="bash"><br />
define google_dns = 8.8.8.8<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Scripting&diff=200Scripting2017-11-19T07:06:01Z<p>Duncan: Update the #! line to include trailing "-f", since all distributed scripts have this and it doesn't work to not have it</p>
<hr />
<div>Many people like to maintain their ruleset in shell scripts, this allows them to add comments and arrange rules in more human-friendly way. This is problematic though since shell scripts break atomicity when applying the ruleset, thus, the filtering policy is applied in an inconsistent way during the ruleset loading time.<br />
<br />
Fortunately, nftables provides a native scripting environment to address these concerns which basically allows you to include other ruleset files, define variables and add comments. You have to restore the content of this native script through the ''nft -f my-ruleset.file'' command.<br />
<br />
To create a nftables script, you have to add the following header to your script file:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft -f<br />
</source><br />
<br />
= Adding comments =<br />
<br />
You can add comments to your file using the '#' character. Everything after the '#' will be ignored.<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft<br />
<br />
#<br />
# table declaration<br />
#<br />
add table filter<br />
<br />
#<br />
# chain declaration<br />
#<br />
add chain filter input { type filter hook input priority 0; policy drop; }<br />
<br />
#<br />
# rule declaration<br />
#<br />
add rule filter input ct state established,related counter accept<br />
</source><br />
<br />
= Including files =<br />
<br />
The example below shows how to include other ruleset files:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft<br />
<br />
include "ipv4-nat.ruleset"<br />
include "ipv6-nat.ruleset"<br />
</source><br />
<br />
= Defining variables =<br />
<br />
You can use the ''define'' keyword to define variables, the following example shows a very simple ruleset to account the traffic that comes from 8.8.8.8 (the popular Google DNS server):<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft<br />
<br />
define google_dns = 8.8.8.8<br />
<br />
add table filter<br />
add chain filter input { type filter hook input priority 0; }<br />
add rule filter input ip saddr $google_dns counter<br />
</source><br />
<br />
You can also define a variable for sets:<br />
<br />
<source lang="bash"><br />
#!/usr/sbin/nft<br />
<br />
define ntp_servers = { 84.77.40.132, 176.31.53.99, 81.19.96.148, 138.100.62.8 }<br />
<br />
add table filter<br />
add chain filter input { type filter hook input priority 0; }<br />
add rule filter input ip saddr $ntp_servers counter<br />
</source><br />
<br />
Don't forget that brackets have special semantics when used from rules, since they indicate that this variable represents a set. Therefore, avoid things like:<br />
<br />
<source lang="bash"><br />
define google_dns = { 8.8.8.8 }<br />
</source><br />
<br />
It is simply overkill to define a set that only stores one single element, instead use the singleton definition:<br />
<br />
<source lang="bash"><br />
define google_dns = 8.8.8.8<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Sets&diff=199Sets2017-11-16T22:48:06Z<p>Duncan: /* Named sets specifications */</p>
<hr />
<div>''nftables'' comes with a built-in generic set infrastructure that allows you to use '''any''' supported selector to build sets. This infrastructure makes possible the representation of [[dictionaries]] and [[maps]].<br />
<br />
The set elements are internally represented using performance data structures such as hashtables and red-black trees.<br />
<br />
= Anonymous sets =<br />
<br />
Anonymous sets are those that are:<br />
<br />
* Bound to a rule, if the rule is removed, that set is released too.<br />
* They have no specific name, the kernel internally allocates an identifier.<br />
* They cannot be updated. So you cannot add and delete elements from it once it is bound to a rule.<br />
<br />
The following example shows how to create a simple set.<br />
<br />
<source lang="bash"><br />
% nft add rule filter output tcp dport { 22, 23 } counter<br />
</source><br />
<br />
This rule above catches all traffic going to TCP ports 22 and 23, in case of matching the counters are updated.<br />
<br />
= Named sets =<br />
<br />
You can create the named sets with the following command:<br />
<br />
<source lang="bash"><br />
% nft add set filter blackhole { type ipv4_addr\;}<br />
</source><br />
<br />
Note that ''blackhole'' is the name of the set in this case. The ''type'' option indicates the data type that this set stores, which is an IPv4 address in the case. Current maximum name length is 16 characters.<br />
<br />
<source lang="bash"><br />
% nft add element filter blackhole { 192.168.3.4 }<br />
% nft add element filter blackhole { 192.168.1.4, 192.168.1.5 }<br />
</source><br />
<br />
Then, you can use it from the rule:<br />
<br />
<source lang="bash"><br />
% nft add rule ip input ip saddr @blackhole drop<br />
</source><br />
<br />
Named sets can be updated anytime, so you can add and delete element from them.<br />
<br />
Eric Leblond in his [https://home.regit.org/2014/01/why-you-will-love-nftables/ Why you will love nftables] article shows a very simple example to compare iptables with nftables:<br />
<br />
<source lang="bash"><br />
ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT<br />
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT<br />
</source><br />
<br />
Which can be expressed in ''nftables'' with a couple of rules that provide a set:<br />
<br />
<source lang="bash"><br />
% nft add rule ip6 filter input tcp dport {telnet, http, https} accept<br />
% nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept<br />
</source><br />
<br />
= Named sets specifications =<br />
<br />
Sets specifications are:<br />
<br />
* '''type''', is obligatory and determines the data type of the set elements. Supported data types currently are:<br />
** ''ipv4_addr'': IPv4 address<br />
** ''ipv6_addr'': IPv6 address.<br />
** ''ether_addr'': Ethernet address.<br />
** ''inet_proto'': Inet protocol type.<br />
** ''inet_service'': Internet service (read tcp port for example)<br />
** ''mark'': Mark type.<br />
<br />
* '''timeout''', it determines how long an element stays in the set. The time string respects the format: ''"v<sub>1</sub>dv<sub>2</sub>hv<sub>3</sub>mv<sub>4</sub>s"'':<br />
<br />
<source lang="bash"><br />
% nft add table filter<br />
% nft add set filter ports {type inet_service \; timeout 3h45s \;}<br />
</source><br />
<br />
These commands create a table named ''filter'' and add a set named ''ports'' to it, where elements are deleted after 3 hours and 45 seconds of being added.<br />
<br />
* '''flags''', the available flags are:<br />
** ''constant'' - set content may not change while bound<br />
** ''interval'' - set contains intervals<br />
** ''timeout'' - elements can be added with a timeout<br />
<br />
Multiple flags should be separated by comma:<br />
<br />
<source lang="bash"><br />
% nft add set filter flags_set {type ipv4_addr\; flags constant, interval\;}<br />
</source><br />
<br />
* '''gc-interval''', stands for garbage collection interval, can only be used if ''timeout'' or ''flags timeout'' are active. The interval follows the same format of ''timeouts'' time string ''"v<sub>1</sub>dv<sub>2</sub>hv<sub>3</sub>mv<sub>4</sub>s"''.<br />
<br />
* '''elements''', initialize the set with some elements in it:<br />
<br />
<source lang="bash"><br />
% nft add set filter daddrs {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}<br />
</source><br />
<br />
This command creates a set name ''daddrs'' with elements ''192.168.1.1'', which stays in it for 10s, and ''192.168.1.2'', which stays for 30s.<br />
<br />
* '''size''', limits the maximum number of elements of the set. To create a set with maximum 2 elements type:<br />
<br />
<source lang="bash"><br />
% nft add set filter saddrs {type ipv4_addr \; size 2 \;}<br />
</source><br />
<br />
* '''policy''', determines set selection policy. Available values are:<br />
** ''performance'' [default]<br />
** ''memory''<br />
<br />
= Listing named sets =<br />
<br />
You can list the content of a named set via:<br />
<br />
<source lang="bash"><br />
% nft list set filter myset<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Performing_Network_Address_Translation_(NAT)&diff=194Performing Network Address Translation (NAT)2017-11-06T00:44:01Z<p>Duncan: Fix idiomatic English expression</p>
<hr />
<div>The ''nat'' chain type allows you to perform NAT. This chain type comes with special semantics:<br />
<br />
* The first packet of a flow is used to look up for a matching rule which sets up the NAT binding for this flow. This also manipulates this first packet accordingly.<br />
* No rule lookup happens for follow up packets in the flow: the NAT engine uses the NAT binding information already set up by the first packet to perform the packet manipulation.<br />
* '''You are required to register both chains (original/reply directions, prerouting/postrouting) in order for the NAT engine to work.'''<br />
<br />
Adding a NAT rule to a filter type chain will result in an error.<br />
<br />
= Stateful NAT =<br />
<br />
The stateful NAT involves the nf_conntrack kernel engine to match/set packet stateful information and will engage according to the state of connections.<br />
This is the most common way of performing NAT and the approach we recommend you to follow.<br />
<br />
Be aware that '''you have to register the prerouting/postrouting chains even if you have no rules there''' since these chain will invoke the NAT engine for the packets coming in the reply direction.<br />
<br />
== Source NAT ==<br />
<br />
If you want to source NAT the traffic that leaves from your local area network to the Internet, you can create a new table ''nat'' with the prerouting and postrouting chains:<br />
<br />
<source lang="bash"><br />
% nft add table nat<br />
% nft add chain nat prerouting { type nat hook prerouting priority 0 \; }<br />
% nft add chain nat postrouting { type nat hook postrouting priority 100 \; }<br />
</source><br />
<br />
Then, add the following rule:<br />
<br />
<source lang="bash"><br />
% nft add rule nat postrouting ip saddr 192.168.1.0/24 oif eth0 snat 1.2.3.4<br />
</source><br />
<br />
This matches for all traffic from the 192.168.1.0/24 network to the interface ''eth0''. The IPv4 address 1.2.3.4 is used as source for the packets that match this rule.<br />
<br />
== Destination NAT ==<br />
<br />
You need to add the following table and chain configuration:<br />
<br />
<source lang="bash"><br />
% nft add table nat<br />
% nft add chain nat prerouting { type nat hook prerouting priority 0 \; }<br />
% nft add chain nat postrouting { type nat hook postrouting priority 100 \; }<br />
</source><br />
<br />
Then, you can add the following rule:<br />
<br />
<source lang="bash"><br />
% nft add rule nat prerouting iif eth0 tcp dport { 80, 443 } dnat 192.168.1.120<br />
</source><br />
<br />
This redirects the incoming traffic for TCP ports 80 and 443 to 192.168.1.120. Don't forget to register the postrouting chain since this invokes the NAT engine for follow up packets going in the reply direction.<br />
<br />
== Masquerading ==<br />
<br />
NOTE: ''masquerade'' is available starting with Linux Kernel 3.18.<br />
<br />
Masquerade is a special case of SNAT, where the source address is automagically set to the address of the output interface. For example:<br />
<br />
<source lang="bash"><br />
% nft add rule nat postrouting masquerade<br />
</source><br />
<br />
Note that:<br />
<br />
# ''masquerade'' only makes sense from postrouting chain of NAT type.<br />
# you still have to add the prerouting nat chain, since this translate traffic in the reply direction.<br />
<br />
<br />
== Redirect ==<br />
<br />
NOTE: ''redirect'' is available starting with Linux Kernel 3.19.<br />
<br />
By using redirect, packets will be forwarded to local machine. Is a special case of DNAT where the destination is the current machine.<br />
<br />
<source lang="bash"><br />
% nft add rule nat prerouting redirect<br />
</source><br />
<br />
This example redirects 22/tcp traffic to 2222/tcp:<br />
<br />
<source lang="bash"><br />
% nft add rule nat prerouting tcp dport 22 redirect to 2222<br />
</source><br />
<br />
Note that:<br />
<br />
# ''redirect'' only makes sense in a prerouting chain of NAT type.<br />
# You still have to register a postrouting nat chain, so the traffic is translated in the reply direction.<br />
<br />
== NAT flags ==<br />
<br />
Since Linux kernel 3.18, you can combine the following flags with your NAT statements:<br />
<br />
* random: randomize source port mapping.<br />
* fully-random: full port randomization.<br />
* persistent: gives a client the same source-/destination-address for each connection.<br />
<br />
For example:<br />
<br />
<source lang="bash"><br />
% nft add rule nat postrouting masquerade random,persistent<br />
% nft add rule nat postrouting ip saddr 192.168.1.0/24 oif eth0 snat 1.2.3.4 fully-random<br />
</source><br />
<br />
== Incompatibilities ==<br />
<br />
You cannot use iptables and nft to perform NAT at the same time. So make sure that the ''iptable_nat'' module is unloaded:<br />
<br />
<source lang="bash"><br />
% rmmod iptable_nat<br />
</source><br />
<br />
= Stateless NAT =<br />
<br />
This type of NAT just modifies each packet according to your rules without any other state/connection tracking.<br />
<br />
This is valid for 1:1 mappings and is faster than stateful NAT. However, it's easy to shoot yourself in the foot.<br />
If your environment doesn't require this approach, better stick to stateful NAT.<br />
<br />
You have to disable connection tracking for modified packets.<br />
<br />
The example below sets IP/port for each packet (also valid in IPv6):<br />
<br />
<source><br />
% nft add rule ip nat prerouting notrack ip protocol tcp ip daddr set 192.168.1.100 tcp dport set 10<br />
% nft add rule ip6 nat prerouting notrack ip6 nexthdr tcp ip6 daddr set fe00::1 tcp dport set 10<br />
</source><br />
<br />
Be sure to check our documentation regarding [[Mangle packet header fields | mangling packets]] and [[setting packet connection tracking metainformation]].<br />
<br />
To use this feature you require nftables >=0.7 and linux kernel >= 4.9.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_metainformation&diff=190Matching packet metainformation2017-10-31T22:38:01Z<p>Duncan: (English) grammar correction: "This faster than" => "This is faster than"</p>
<hr />
<div>''nftables'' comes with the packet metainformation selectors that you can use to match information that is stored in the network packet. <br />
<br />
= The meta selectors =<br />
<br />
The current metainformation that you can match is:<br />
<br />
* interface device name and interface device index: ''iifname, ''oifname'', ''iif'' and ''oif''.<br />
* interface type: ''iiftyte'' and ''oiftype''.<br />
* tc handle: ''priority''.<br />
* socket user and group identifier: ''skuid'' and ''skgid''.<br />
* packet length: ''length''.<br />
<br />
== Matching packets by interface name ==<br />
<br />
You can use the following selectors to match the interface name:<br />
<br />
* ''iifname'', to match the input network interface name.<br />
* ''oifname'', to match the output network interface name.<br />
* ''iif'', to match the interface index of the network interface name. This is faster than ''iifname'' as it only has to compare a 32-bits unsigned integer instead of a string. The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ''ppp0''.<br />
* ''oif'', like ''iif'' but it matches the output network interface index.<br />
<br />
An example usage of the interface name is the following:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input meta oifname lo accept<br />
</source><br />
<br />
This rule accepts all traffic for the loopback pseudodevice ''lo''.<br />
<br />
== Matching packets by packet mark ==<br />
<br />
You can match packets whose mark is 123 with the following rule:<br />
<br />
<source lang="bash"><br />
nft add rule filter output meta mark 123 counter<br />
</source><br />
<br />
== Matching packets the socket UID ==<br />
<br />
You can use your user name to match traffic, eg.<br />
<br />
<source lang="bash"><br />
% nft add rule filter output meta skuid pablo counter<br />
</source><br />
<br />
Or the 32-bits unsigned integer (UID) in case there is no entry in /etc/passwd for a given user.<br />
<br />
<source lang="bash"><br />
% nft add rule filter output meta skuid 1000 counter<br />
</source><br />
<br />
Let's just generate some HTTP traffic to test this rule:<br />
<br />
<source lang="bash"><br />
% wget --spider http://www.google.com<br />
</source><br />
<br />
Then, if you check the counters, you can verify that the packets are matching that rule.<br />
<br />
<source lang="bash"><br />
% nft list table filter<br />
table ip filter {<br />
chain output {<br />
type filter hook output priority 0;<br />
skuid pablo counter packets 7 bytes 510<br />
}<br />
<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
}<br />
</source><br />
<br />
'''Important''': Beware if you test this with ''ping'', it is usually installed with suid so that traffic will match the root user (uid=0).<br />
<br />
== Matching packet priority ==<br />
<br />
Since nftables v0.7 you can match the packet priority, the tc classid:<br />
<br />
<source><br />
% nft add rule filter forward meta priority abcd:1234<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=189Matching packet headers2017-10-24T06:57:24Z<p>Duncan: (English) grammar correction: "all ICMP echo request (popularly known as ''ping'')" => "all ICMP echo requests (popularly known as ''pings'')"</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use a binary operation. For example, to count packets that are not SYN ones:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packets with flags SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo requests (popularly known as ''pings'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=188Matching packet headers2017-10-24T06:54:08Z<p>Duncan: (English) grammar correction: "with flag SYN and ACK set" => "with flags SYN and ACK set"</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use a binary operation. For example, to count packets that are not SYN ones:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packets with flags SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo request (popularly known as ''ping'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=187Matching packet headers2017-10-24T06:52:20Z<p>Duncan: (English) grammar correction: "count and log TCP packet" => "count and log TCP packets"</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use a binary operation. For example, to count packets that are not SYN ones:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packets with flag SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo request (popularly known as ''ping'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=186Matching packet headers2017-10-24T06:47:44Z<p>Duncan: (English) grammar correction: "need to use binary operation" => "need to use a binary operation"</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use a binary operation. For example, to count packets that are not SYN ones:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packet with flag SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo request (popularly known as ''ping'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=185Matching packet headers2017-10-24T06:41:50Z<p>Duncan: (English) grammar correction: "examples shows" => "examples show"</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use binary operation. For example, to count packet that are not SYN one:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packet with flag SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo request (popularly known as ''ping'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Matching_packet_headers&diff=184Matching packet headers2017-10-24T06:33:47Z<p>Duncan: Fix typo in /* Maching Ethernet header fields */</p>
<hr />
<div>The ''nft'' command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.<br />
<br />
= Matching transport protocol =<br />
<br />
The following rule shows how to match any kind of ''TCP'' traffic:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip protocol tcp<br />
</source><br />
<br />
= Matching Ethernet header fields =<br />
<br />
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:<br />
<br />
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter <br />
<br />
Do not forget that the layer 2 header information is only available in the input path.<br />
<br />
= Matching IPv4 header fields =<br />
<br />
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).<br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''protocol'' keyword:<br />
<source lang="bash"><br />
% nft add rule filter input protocol tcp counter<br />
</source><br />
<br />
= Matching IPv6 header fields =<br />
<br />
If you want to account IPv6 traffic that is addressed to ''abdc::100'', you can type the following command:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip6 daddr abcd::100 counter<br />
</source><br />
<br />
To filter on a layer 4 protocol like TCP, you can use the ''nexthdr'' keyword:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input ip6 nexthdr tcp counter<br />
</source><br />
<br />
Do not forget to create an ''ip6'' [[Configuring tables|table]] and register the corresponding [[Configuring chains|chains]] to run the examples.<br />
<br />
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'<br />
<br />
= Matching TCP/UDP/UDPlite traffic =<br />
<br />
The following examples shows how to drop all tcp traffic for low TCP ports (1-1024):<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp dport 1-1024 counter drop<br />
</source><br />
<br />
Note that this rule is using an [[intervals|interval]] (from 1 to 1024).<br />
<br />
To match on TCP flags, you need to use binary operation. For example, to count packet that are not SYN one:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input tcp flags != syn counter<br />
</source><br />
<br />
More complex filters can be used. For example, to count and log TCP packet with flag SYN and ACK set:<br />
<br />
<source lang="bash"><br />
% nft -i<br />
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log<br />
</source><br />
<br />
= Matching ICMP traffic =<br />
<br />
You can drop all ICMP echo request (popularly known as ''ping'') via:<br />
<br />
<source lang="bash"><br />
% nft add rule filter input icmp type echo-request counter drop<br />
</source><br />
<br />
Here is the list of available icmp types:<br />
<br />
* echo-reply<br />
* destination-unreachable<br />
* source-quench<br />
* redirect<br />
* echo-request<br />
* time-exceeded<br />
* parameter-problem<br />
* timestamp-request<br />
* timestamp-reply<br />
* info-request<br />
* info-reply<br />
* address-mask-request<br />
* address-mask-reply</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Simple_rule_management&diff=177Simple rule management2017-10-07T00:54:36Z<p>Duncan: /* Replacing rules */</p>
<hr />
<div>= Appending new rules =<br />
<br />
To add new rules, you have to specify the corresponding table and the chain that you want to use, eg.<br />
<br />
<source lang="bash"><br />
% nft add rule filter output ip daddr 8.8.8.8 counter<br />
</source><br />
<br />
Where ''filter'' is the table and ''output'' is the chain. The example above adds a rule to match all packets seen by the output chain whose destination is 8.8.8.8, in case of matching it updates the rule counters. Note that counters are optional in ''nftables''.<br />
<br />
For those familiar with iptables, the rule appending is equivalent to ''-A'' command in iptables.<br />
<br />
= Listing rules =<br />
<br />
You can list the rules that are contained by a table with the following command:<br />
<br />
<source lang="bash"><br />
% nft list table filter<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
<br />
chain output {<br />
type filter hook output priority 0;<br />
ip daddr google-public-dns-a.google.com counter packets 0 bytes 0<br />
}<br />
}<br />
</source><br />
<br />
Assuming we also add a rule that uses a port:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output tcp dport ssh counter<br />
</source><br />
<br />
You can disable host name resolution via using the ''-n'' option:<br />
<br />
<source lang="bash"><br />
% nft list -n table filter<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
<br />
chain output {<br />
type filter hook output priority 0;<br />
ip daddr 8.8.8.8 counter packets 0 bytes 0<br />
tcp dport ssh counter packets 0 bytes 0<br />
}<br />
}<br />
</source><br />
<br />
You can also disable service name resolution via ''-nn'':<br />
<br />
<source lang="bash"><br />
% nft list -nn table filter<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
<br />
chain output {<br />
type filter hook output priority 0;<br />
ip daddr 8.8.8.8 counter packets 0 bytes 0<br />
tcp dport 22 counter packets 0 bytes 0<br />
}<br />
}<br />
</source><br />
<br />
= Testing your rule =<br />
<br />
Let's test this rule with a simple ping to 192.168.1.1:<br />
<br />
<source lang="bash"><br />
% ping -c 1 8.8.8.8<br />
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.<br />
64 bytes from 8.8.8.8: icmp_req=1 ttl=64 time=1.31 ms<br />
</source><br />
<br />
Then, if we list the rule-set, we obtain:<br />
<br />
<source lang="bash"><br />
% nft -nn list table filter<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
<br />
chain output {<br />
type filter hook output priority 0;<br />
ip daddr 8.8.8.8 counter packets 1 bytes 84<br />
tcp dport 22 counter packets 0 bytes 0<br />
}<br />
}<br />
</source><br />
<br />
Note that the counters have been updated.<br />
<br />
= Adding a rule at a given position =<br />
<br />
If you want to add a rule at a given position, you have to use the handle as reference:<br />
<br />
<source lang="bash"><br />
% nft list table filter -n -a<br />
table filter {<br />
chain output {<br />
type filter hook output priority 0;<br />
ip protocol tcp counter packets 82 bytes 9680 # handle 8<br />
ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7<br />
}<br />
}<br />
</source><br />
<br />
If you want to add a rule after the rule with handler number 8, you have to type:<br />
<br />
<source lang="bash"><br />
% nft add rule filter output position 8 ip daddr 127.0.0.8 drop <br />
</source><br />
<br />
Now, you can check the effect of that command by listing the rule-set:<br />
<br />
<source lang="bash"><br />
% nft list table filter -n -a<br />
table filter {<br />
chain output {<br />
type filter hook output priority 0;<br />
ip protocol tcp counter packets 190 bytes 21908 # handle 8<br />
ip daddr 127.0.0.8 drop # handle 10<br />
ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7<br />
}<br />
}<br />
</source><br />
<br />
If you want to insert a rule before the rule with handler number 8, you have to type:<br />
<br />
<source lang="bash"><br />
% nft insert rule filter output position 8 ip daddr 127.0.0.8 drop <br />
</source><br />
<br />
= Removing rules =<br />
<br />
You have to obtain the ''handle'' to delete a rule via the '''-a''' option. The ''handle'' is automagically assigned by the kernel and it uniquely identifies the rule.<br />
<br />
<source lang="bash"><br />
% nft list table filter -a<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0;<br />
}<br />
<br />
chain output {<br />
type filter hook output priority 0;<br />
ip daddr 192.168.1.1 counter packets 1 bytes 84 # handle 5<br />
}<br />
}<br />
</source><br />
<br />
You can delete the rule whose handle is ''5'' with the following command:<br />
<br />
<source lang="bash"><br />
% nft delete rule filter output handle 5<br />
</source><br />
<br />
'''Note''': There are plans to support rule deletion by passing:<br />
<source lang="bash"><br />
% nft delete rule filter output ip saddr 192.168.1.1 counter<br />
</source><br />
<br />
but this is '''not''' yet implemented. So you'll have to use the handle to delete rules until that feature is implemented.<br />
<br />
= Removing all the rules in a chain =<br />
<br />
You can delete '''all the rules''' in a chain with the following command:<br />
<br />
<source lang="bash"><br />
% nft delete rule filter output<br />
</source><br />
<br />
You can also delete '''all the rules''' in a table with the following command:<br />
<br />
<source lang="bash"><br />
% nft flush table filter<br />
</source><br />
<br />
= Prepending new rules =<br />
<br />
To prepend new rules through the ''insert'' command:<br />
<br />
<source lang="bash"><br />
% nft insert rule filter output ip daddr 192.168.1.1 counter<br />
</source><br />
<br />
This prepends a rule that will update per-rule packet and bytes counters for traffic addressed to 192.168.1.1.<br />
<br />
The equivalent in iptables is:<br />
<br />
<source lang="bash"><br />
% iptables -I OUTPUT -t filter -d 192.168.1.1<br />
</source><br />
<br />
Note that iptables always provides per-rule counters.<br />
<br />
= Replacing rules =<br />
<br />
You can replace any rule via the ''replace'' command by indicating the rule handle. Therefore, first you have to list the ruleset with option ''-a'' to obtain the rule handle.<br />
<br />
<source lang="bash"><br />
# nft list ruleset -a<br />
table ip filter {<br />
chain input {<br />
type filter hook input priority 0; policy accept;<br />
ip protocol tcp counter packets 0 bytes 0 # handle 2<br />
}<br />
}<br />
</source><br />
<br />
Then, assuming you want to replace rule with handle number 2, you have to specify this handle number and the new rule that you want to place instead of it:<br />
<br />
<source lang="bash"><br />
nft replace rule filter input handle 2 counter<br />
</source><br />
<br />
Then, when listing back the ruleset:<br />
<br />
<source lang="bash"><br />
# nft list ruleset -a<br />
table ip filter {<br />
chain input {<br />
counter packets 0 bytes 0 <br />
}<br />
}<br />
</source><br />
<br />
You can effective note that the rule has been replaced by a simple rule that counts any packets, instead of counting TCP packets as the previous rule was doing.</div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Quick_reference-nftables_in_10_minutes&diff=174Quick reference-nftables in 10 minutes2017-09-24T00:50:18Z<p>Duncan: /* Rules */</p>
<hr />
<div>Find below some basic concepts to know before using nftables.<br />
<br />
'''table''' refers to a container of [[Configuring chains|chains]] with no specific semantics.<br />
<br />
'''chain''' within a [[Configuring tables|table]] refers to a container of [[Rule_management|rules]].<br />
<br />
'''rule''' refers to an action to be configured within a ''chain''.<br />
<br />
<br />
= nft command line =<br />
<br />
''nft'' is the command line tool in order to interact with nftables at userspace.<br />
<br />
== Tables ==<br />
<br />
'''family''' refers to a one of the following table types: ''ip'', ''arp'', ''ip6'', ''bridge'', ''inet'', ''netdev''.<br />
<br />
<source lang="bash"><br />
% nft list tables [<family>]<br />
% nft list table [<family>] <name> [-n] [-a]<br />
% nft (add | delete | flush) table [<family>] <name><br />
</source><br />
<br />
The argument ''-n'' shows the addresses and other information that uses names in numeric format. The ''-a'' argument is used to display the ''handle''.<br />
<br />
== Chains ==<br />
<br />
'''type''' refers to the kind of chain to be created. Possible types are:<br />
<br />
* ''filter'': Supported by ''arp'', ''bridge'', ''ip'', ''ip6'' and ''inet'' table families.<br />
* ''route'': Mark packets (like mangle for the ''output'' hook, for other hooks use the type ''filter'' instead), supported by ''ip'' and ''ip6''.<br />
* ''nat'': In order to perform Network Address Translation, supported by ''ip'' and ''ip6''.<br />
<br />
'''hook''' refers to an specific stage of the packet while it's being processed through the kernel. More info in [[Netfilter_hooks|Netfilter hooks]].<br />
<br />
* The hooks for ''ip'', ''ip6'' and ''inet'' families are: ''prerouting'', ''input'', ''forward'', ''output'', ''postrouting''.<br />
* The hooks for ''arp'' family are: '' input'', ''output''.<br />
* The ''bridge'' family handles ethernet packets traversing bridge devices.<br />
* The hook for ''netdev'' is: ''ingress''.<br />
<br />
'''priority''' refers to a number used to order the chains or to set them between some Netfilter operations. Possible values are: ''NF_IP_PRI_CONNTRACK_DEFRAG (-400)'', ''NF_IP_PRI_RAW (-300)'', ''NF_IP_PRI_SELINUX_FIRST (-225)'', ''NF_IP_PRI_CONNTRACK (-200)'', ''NF_IP_PRI_MANGLE (-150)'', ''NF_IP_PRI_NAT_DST (-100)'', ''NF_IP_PRI_FILTER (0)'', ''NF_IP_PRI_SECURITY (50)'', ''NF_IP_PRI_NAT_SRC (100)'', ''NF_IP_PRI_SELINUX_LAST (225)'', ''NF_IP_PRI_CONNTRACK_HELPER (300)''.<br />
<br />
'''policy''' is the default verdict statement to control the flow in the chain. Possible values are: ''accept'', ''drop'', ''queue'', ''continue'', ''return''.<br />
<br />
<source lang="bash"><br />
% nft (add | create) chain [<family>] <table> <name> [ { type <type> hook <hook> [device <device>] priority <priority> \; [policy <policy> \;] } ]<br />
% nft (delete | list | flush) chain [<family>] <table> <name><br />
% nft rename chain [<family>] <table> <name> <newname><br />
</source><br />
<br />
== Rules ==<br />
<br />
'''handle''' is an internal number that identifies a certain ''rule''.<br />
<br />
'''position''' is an internal number that is used to insert a ''rule'' before a certain ''handle''.<br />
<br />
<source lang="bash"><br />
% nft add rule [<family>] <table> <chain> <matches> <statements><br />
% nft insert rule [<family>] <table> <chain> [position <position>] <matches> <statements><br />
% nft replace rule [<family>] <table> <chain> [handle <handle>] <matches> <statements><br />
% nft delete rule [<family>] <table> <chain> [handle <handle>]<br />
</source><br />
<br />
=== Matches ===<br />
<br />
'''matches''' are clues used to access to certain packet information and create filters according to them.<br />
<br />
==== Ip ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|ip match<br />
|-<br />
| | ''dscp <value>''<br />
|<br />
|<source lang="bash"><br />
ip dscp cs1<br />
ip dscp != cs1<br />
ip dscp 0x38<br />
ip dscp != 0x20<br />
ip dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, <br />
af22, af23, af31, af32, af33, af41, af42, af43, ef}<br />
</source><br />
|-<br />
| ''length <length>''<br />
| Total packet length<br />
|<source lang="bash"><br />
ip length 232<br />
ip length != 233<br />
ip length 333-435<br />
ip length != 333-453<br />
ip length { 333, 553, 673, 838}<br />
</source><br />
|-<br />
| ''id <id>''<br />
| IP ID<br />
|<source lang="bash"><br />
ip id 22<br />
ip id != 233<br />
ip id 33-45<br />
ip id != 33-45<br />
ip id { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''frag-off <value>''<br />
| Fragmentation offset<br />
|<source lang="bash"><br />
ip frag-off 222<br />
ip frag-off != 233<br />
ip frag-off 33-45<br />
ip frag-off != 33-45<br />
ip frag-off { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''ttl <ttl>''<br />
| Time to live<br />
|<source lang="bash"><br />
ip ttl 0<br />
ip ttl 233<br />
ip ttl 33-55<br />
ip ttl != 45-50<br />
ip ttl { 43, 53, 45 }<br />
ip ttl { 33-55 }<br />
</source><br />
|-<br />
| ''protocol <protocol>''<br />
| Upper layer protocol<br />
|<source lang="bash"><br />
ip protocol tcp<br />
ip protocol 6<br />
ip protocol != tcp<br />
ip protocol { icmp, esp, ah, comp, udp, udplite, tcp, dccp, sctp }<br />
</source><br />
|-<br />
| ''checksum <checksum>''<br />
| IP header checksum<br />
|<source lang="bash"><br />
ip checksum 13172<br />
ip checksum 22<br />
ip checksum != 233<br />
ip checksum 33-45<br />
ip checksum != 33-45<br />
ip checksum { 33, 55, 67, 88 }<br />
ip checksum { 33-55 }<br />
</source><br />
|-<br />
| ''saddr <ip source address>''<br />
| Source address<br />
|<source lang="bash"><br />
ip saddr 192.168.2.0/24<br />
ip saddr != 192.168.2.0/24<br />
ip saddr 192.168.3.1 ip daddr 192.168.3.100<br />
ip saddr != 1.1.1.1<br />
ip saddr 1.1.1.1<br />
ip saddr & 0xff == 1<br />
ip saddr & 0.0.0.255 < 0.0.0.127<br />
</source><br />
|-<br />
| ''daddr <ip destination address>''<br />
| Destination address<br />
|<source lang="bash"><br />
ip daddr 192.168.0.1<br />
ip daddr != 192.168.0.1<br />
ip daddr 192.168.0.1-192.168.0.250<br />
ip daddr 10.0.0.0-10.255.255.255<br />
ip daddr 172.16.0.0-172.31.255.255<br />
ip daddr 192.168.3.1-192.168.4.250<br />
ip daddr != 192.168.0.1-192.168.0.250<br />
ip daddr { 192.168.0.1-192.168.0.250 }<br />
ip daddr { 192.168.5.1, 192.168.5.2, 192.168.5.3 }<br />
</source><br />
|-<br />
| ''version <version>''<br />
| Ip Header version<br />
|<source lang="bash"><br />
ip version 4<br />
</source><br />
|-<br />
| ''hdrlength <header length>''<br />
| IP header length<br />
|<source lang="bash"><br />
ip hdrlength 0<br />
ip hdrlength 15<br />
</source><br />
|}<br />
<br />
==== Ip6 ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|ip6 match<br />
|-<br />
| ''dscp <value>''<br />
| <br />
|<source lang="bash"><br />
ip6 dscp cs1<br />
ip6 dscp != cs1<br />
ip6 dscp 0x38<br />
ip6 dscp != 0x20<br />
ip6 dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef}<br />
</source><br />
|-<br />
| ''flowlabel <label>''<br />
| Flow label<br />
|<source lang="bash"><br />
ip6 flowlabel 22<br />
ip6 flowlabel != 233<br />
ip6 flowlabel { 33, 55, 67, 88 }<br />
ip6 flowlabel { 33-55 }<br />
</source><br />
|-<br />
| ''length <length>''<br />
| Payload length<br />
|<source lang="bash"><br />
ip6 length 232<br />
ip6 length != 233<br />
ip6 length 333-435<br />
ip6 length != 333-453<br />
ip6 length { 333, 553, 673, 838}<br />
</source><br />
|-<br />
| ''nexthdr <header>''<br />
| Next header type (Upper layer protocol number)<br />
|<source lang="bash"><br />
ip6 nexthdr {esp, udp, ah, comp, udplite, tcp, dccp, sctp, icmpv6}<br />
ip6 nexthdr esp<br />
ip6 nexthdr != esp<br />
ip6 nexthdr { 33-44 }<br />
ip6 nexthdr 33-44<br />
ip6 nexthdr != 33-44<br />
</source><br />
|-<br />
| ''hoplimit <hoplimit>''<br />
| Hop limit<br />
|<source lang="bash"><br />
ip6 hoplimit 1<br />
ip6 hoplimit != 233<br />
ip6 hoplimit 33-45<br />
ip6 hoplimit != 33-45<br />
ip6 hoplimit {33, 55, 67, 88}<br />
ip6 hoplimit {33-55}<br />
</source><br />
|-<br />
| ''saddr <ip source address>''<br />
| Source Address<br />
|<source lang="bash"><br />
ip6 saddr 1234:1234:1234:1234:1234:1234:1234:1234<br />
ip6 saddr ::1234:1234:1234:1234:1234:1234:1234<br />
ip6 saddr ::/64<br />
ip6 saddr ::1 ip6 daddr ::2<br />
</source><br />
|-<br />
| ''daddr <ip destination address>''<br />
| Destination Address<br />
|<source lang="bash"><br />
ip6 daddr 1234:1234:1234:1234:1234:1234:1234:1234<br />
ip6 daddr != ::1234:1234:1234:1234:1234:1234:1234-1234:1234::1234:1234:1234:1234:1234<br />
</source><br />
|-<br />
| ''version <version>''<br />
| IP header version<br />
|<source lang="bash"><br />
ip6 version 6<br />
</source><br />
|}<br />
<br />
<br />
==== Tcp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|tcp match<br />
|-<br />
| ''dport <destination port>''<br />
| Destination port<br />
|<source lang="bash"><br />
tcp dport 22<br />
tcp dport != 33-45<br />
tcp dport { 33-55 }<br />
tcp dport {telnet, http, https }<br />
tcp dport vmap { 22 : accept, 23 : drop }<br />
tcp dport vmap { 25:accept, 28:drop }<br />
</source><br />
|-<br />
| ''sport < source port>''<br />
| Source port<br />
|<source lang="bash"><br />
tcp sport 22<br />
tcp sport != 33-45<br />
tcp sport { 33, 55, 67, 88}<br />
tcp sport { 33-55}<br />
tcp sport vmap { 25:accept, 28:drop }<br />
tcp sport 1024 tcp dport 22<br />
</source><br />
|-<br />
| ''sequence <value>''<br />
| Sequence number<br />
|<source lang="bash"><br />
tcp sequence 22<br />
tcp sequence != 33-45<br />
</source><br />
|-<br />
| ''ackseq <value>''<br />
| Acknowledgement number<br />
|<source lang="bash"><br />
tcp ackseq 22<br />
tcp ackseq != 33-45<br />
tcp ackseq { 33, 55, 67, 88 }<br />
tcp ackseq { 33-55 }<br />
</source><br />
|-<br />
| ''flags <flags>''<br />
| TCP flags<br />
|<source lang="bash"><br />
tcp flags { fin, syn, rst, psh, ack, urg, ecn, cwr}<br />
tcp flags cwr<br />
tcp flags != cwr<br />
</source><br />
|-<br />
| ''window <value>''<br />
| Window<br />
|<source lang="bash"><br />
tcp window 22<br />
tcp window != 33-45<br />
tcp window { 33, 55, 67, 88 }<br />
tcp window { 33-55 }<br />
</source><br />
|-<br />
| ''checksum <checksum>''<br />
| IP header checksum<br />
|<source lang="bash"><br />
tcp checksum 22<br />
tcp checksum != 33-45<br />
tcp checksum { 33, 55, 67, 88 }<br />
tcp checksum { 33-55 }<br />
</source><br />
|-<br />
| ''urgptr <pointer>''<br />
| Urgent pointer<br />
|<source lang="bash"><br />
tcp urgptr 22<br />
tcp urgptr != 33-45<br />
tcp urgptr { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''doff <offset>''<br />
| Data offset<br />
|<source lang="bash"><br />
tcp doff 8<br />
</source><br />
|}<br />
<br />
<br />
==== Udp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|udp match<br />
|-<br />
| ''dport <destination port>''<br />
| Destination port<br />
|<source lang="bash"><br />
udp dport 22<br />
udp dport != 33-45<br />
udp dport { 33-55 }<br />
udp dport {telnet, http, https }<br />
udp dport vmap { 22 : accept, 23 : drop }<br />
udp dport vmap { 25:accept, 28:drop }<br />
</source><br />
|-<br />
| ''sport < source port>''<br />
| Source port<br />
|<source lang="bash"><br />
udp sport 22<br />
udp sport != 33-45<br />
udp sport { 33, 55, 67, 88}<br />
udp sport { 33-55}<br />
udp sport vmap { 25:accept, 28:drop }<br />
udp sport 1024 tcp dport 22<br />
</source><br />
|-<br />
| ''length <length>''<br />
| Total packet length<br />
|<source lang="bash"><br />
udp length 6666<br />
udp length != 50-65<br />
udp length { 50, 65 }<br />
udp length { 35-50 }<br />
</source><br />
|-<br />
| ''checksum <checksum>''<br />
| UDP checksum<br />
|<source lang="bash"><br />
udp checksum 22<br />
udp checksum != 33-45<br />
udp checksum { 33, 55, 67, 88 }<br />
udp checksum { 33-55 }<br />
</source><br />
|}<br />
<br />
<br />
==== Udplite ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|udplite match<br />
|-<br />
| ''dport <destination port>''<br />
| Destination port<br />
|<source lang="bash"><br />
udplite dport 22<br />
udplite dport != 33-45<br />
udplite dport { 33-55 }<br />
udplite dport {telnet, http, https }<br />
udplite dport vmap { 22 : accept, 23 : drop }<br />
udplite dport vmap { 25:accept, 28:drop }<br />
</source><br />
|-<br />
| ''sport < source port>''<br />
| Source port<br />
|<source lang="bash"><br />
udplite sport 22<br />
udplite sport != 33-45<br />
udplite sport { 33, 55, 67, 88}<br />
udplite sport { 33-55}<br />
udplite sport vmap { 25:accept, 28:drop }<br />
udplite sport 1024 tcp dport 22<br />
</source><br />
|-<br />
| ''checksum <checksum>''<br />
| Checksum<br />
|<source lang="bash"><br />
udplite checksum 22<br />
udplite checksum != 33-45<br />
udplite checksum { 33, 55, 67, 88 }<br />
udplite checksum { 33-55 }<br />
</source><br />
|}<br />
<br />
<br />
==== Sctp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|sctp match<br />
|-<br />
| ''dport <destination port>''<br />
| Destination port<br />
|<source lang="bash"><br />
sctp dport 22<br />
sctp dport != 33-45<br />
sctp dport { 33-55 }<br />
sctp dport {telnet, http, https }<br />
sctp dport vmap { 22 : accept, 23 : drop }<br />
sctp dport vmap { 25:accept, 28:drop }<br />
</source><br />
|-<br />
| ''sport < source port>''<br />
| Source port<br />
|<source lang="bash"><br />
sctp sport 22<br />
sctp sport != 33-45<br />
sctp sport { 33, 55, 67, 88}<br />
sctp sport { 33-55}<br />
sctp sport vmap { 25:accept, 28:drop }<br />
sctp sport 1024 tcp dport 22<br />
</source><br />
|-<br />
| ''checksum <checksum>''<br />
| Checksum<br />
|<source lang="bash"><br />
sctp checksum 22<br />
sctp checksum != 33-45<br />
sctp checksum { 33, 55, 67, 88 }<br />
sctp checksum { 33-55 }<br />
</source><br />
|-<br />
| ''vtag <tag>''<br />
| Verification tag<br />
|<source lang="bash"><br />
sctp vtag 22<br />
sctp vtag != 33-45<br />
sctp vtag { 33, 55, 67, 88 }<br />
sctp vtag { 33-55 }<br />
</source><br />
|}<br />
<br />
<br />
==== Dccp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|dccp match<br />
|-<br />
| ''dport <destination port>''<br />
| Destination port<br />
|<source lang="bash"><br />
dccp dport 22<br />
dccp dport != 33-45<br />
dccp dport { 33-55 }<br />
dccp dport {telnet, http, https }<br />
dccp dport vmap { 22 : accept, 23 : drop }<br />
dccp dport vmap { 25:accept, 28:drop }<br />
</source><br />
|-<br />
| ''sport < source port>''<br />
| Source port<br />
|<source lang="bash"><br />
dccp sport 22<br />
dccp sport != 33-45<br />
dccp sport { 33, 55, 67, 88}<br />
dccp sport { 33-55}<br />
dccp sport vmap { 25:accept, 28:drop }<br />
dccp sport 1024 tcp dport 22<br />
</source><br />
|-<br />
| ''type <type>''<br />
| Type of packet<br />
|<source lang="bash"><br />
dccp type {request, response, data, ack, dataack, closereq, close, reset, sync, syncack}<br />
dccp type request<br />
dccp type != request<br />
</source><br />
|}<br />
<br />
<br />
==== Ah ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|ah match<br />
|-<br />
| ''hdrlength <length>''<br />
| AH header length<br />
|<source lang="bash"><br />
ah hdrlength 11-23<br />
ah hdrlength != 11-23<br />
ah hdrlength {11, 23, 44 }<br />
</source><br />
|-<br />
| ''reserved <value>''<br />
| <br />
|<source lang="bash"><br />
ah reserved 22<br />
ah reserved != 33-45<br />
ah reserved {23, 100 }<br />
ah reserved { 33-55 }<br />
</source><br />
|-<br />
| ''spi <value>''<br />
| <br />
|<source lang="bash"><br />
ah spi 111<br />
ah spi != 111-222<br />
ah spi {111, 122 }<br />
</source><br />
|-<br />
| ''sequence <sequence>''<br />
| Sequence Number<br />
|<source lang="bash"><br />
ah sequence 123<br />
ah sequence {23, 25, 33}<br />
ah sequence != 23-33<br />
</source><br />
|}<br />
<br />
<br />
==== Esp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|esp match<br />
|-<br />
| ''spi <value>''<br />
| <br />
|<source lang="bash"><br />
esp spi 111<br />
esp spi != 111-222<br />
esp spi {111, 122 }<br />
</source><br />
|-<br />
| ''sequence <sequence>''<br />
| Sequence Number<br />
|<source lang="bash"><br />
esp sequence 123<br />
esp sequence {23, 25, 33}<br />
esp sequence != 23-33<br />
</source><br />
|}<br />
<br />
<br />
==== Comp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|comp match<br />
|-<br />
| ''nexthdr <protocol>''<br />
| Next header protocol (Upper layer protocol)<br />
|<source lang="bash"><br />
comp nexthdr != esp<br />
comp nexthdr {esp, ah, comp, udp, udplite, tcp, tcp, dccp, sctp}<br />
</source><br />
|-<br />
| ''flags <flags>''<br />
| Flags<br />
|<source lang="bash"><br />
comp flags 0x0<br />
comp flags != 0x33-0x45<br />
comp flags {0x33, 0x55, 0x67, 0x88}<br />
</source><br />
|-<br />
| ''cpi <value>''<br />
| Compression Parameter Index<br />
|<source lang="bash"><br />
comp cpi 22<br />
comp cpi != 33-45<br />
comp cpi {33, 55, 67, 88}<br />
</source><br />
|}<br />
<br />
<br />
==== Icmp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|icmp match<br />
|-<br />
| ''type <type>''<br />
| ICMP packet type<br />
|<source lang="bash"><br />
icmp type {echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation}<br />
</source><br />
|-<br />
| ''code <code>''<br />
| ICMP packet code<br />
|<source lang="bash"><br />
icmp code 111<br />
icmp code != 33-55<br />
icmp code { 2, 4, 54, 33, 56}<br />
</source><br />
|-<br />
| ''checksum <value>''<br />
| ICMP packet checksum<br />
|<source lang="bash"><br />
icmp checksum 12343<br />
icmp checksum != 11-343<br />
icmp checksum { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''id <value>''<br />
| ICMP packet id<br />
|<source lang="bash"><br />
icmp id 12343<br />
icmp id != 11-343<br />
icmp id { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''sequence <value>''<br />
| ICMP packet sequence<br />
|<source lang="bash"><br />
icmp sequence 12343<br />
icmp sequence != 11-343<br />
icmp sequence { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''mtu <value>''<br />
| ICMP packet mtu<br />
|<source lang="bash"><br />
icmp mtu 12343<br />
icmp mtu != 11-343<br />
icmp mtu { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''gateway <value>''<br />
| ICMP packet gateway<br />
|<source lang="bash"><br />
icmp gateway 12343<br />
icmp gateway != 11-343<br />
icmp gateway { 1111, 222, 343 }<br />
</source><br />
|}<br />
<br />
<br />
==== Icmpv6 ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|icmpv6 match<br />
|-<br />
| ''type <type>''<br />
| ICMPv6 packet type<br />
|<source lang="bash"><br />
icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect, parameter-problem, router-renumbering}<br />
</source><br />
|-<br />
| ''code <code>''<br />
| ICMPv6 packet code<br />
|<source lang="bash"><br />
icmpv6 code 4<br />
icmpv6 code 3-66<br />
icmpv6 code {5, 6, 7}<br />
</source><br />
|-<br />
| ''checksum <value>''<br />
| ICMPv6 packet checksum<br />
|<source lang="bash"><br />
icmpv6 checksum 12343<br />
icmpv6 checksum != 11-343<br />
icmpv6 checksum { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''id <value>''<br />
| ICMPv6 packet id<br />
|<source lang="bash"><br />
icmpv6 id 12343<br />
icmpv6 id != 11-343<br />
icmpv6 id { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''sequence <value>''<br />
| ICMPv6 packet sequence<br />
|<source lang="bash"><br />
icmpv6 sequence 12343<br />
icmpv6 sequence != 11-343<br />
icmpv6 sequence { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''mtu <value>''<br />
| ICMPv6 packet mtu<br />
|<source lang="bash"><br />
icmpv6 mtu 12343<br />
icmpv6 mtu != 11-343<br />
icmpv6 mtu { 1111, 222, 343 }<br />
</source><br />
|-<br />
| ''max-delay <value>''<br />
| ICMPv6 packet max delay<br />
|<source lang="bash"><br />
icmpv6 max-delay 33-45<br />
icmpv6 max-delay != 33-45<br />
icmpv6 max-delay {33, 55, 67, 88}<br />
</source><br />
|}<br />
<br />
<br />
==== Ether ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|ether match<br />
|-<br />
| ''saddr <mac address>''<br />
| Source mac address<br />
|<source lang="bash"><br />
ether saddr 00:0f:54:0c:11:04<br />
</source><br />
|-<br />
| ''type <type>''<br />
| <br />
|<source lang="bash"><br />
ether type vlan<br />
</source><br />
|}<br />
<br />
==== Dst ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|dst match<br />
|-<br />
| ''nexthdr <proto>''<br />
| Next protocol header<br />
|<source lang="bash"><br />
dst nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp}<br />
dst nexthdr 22<br />
dst nexthdr != 33-45<br />
</source><br />
|-<br />
| ''hdrlength <length>''<br />
| Header Length<br />
|<source lang="bash"><br />
dst hdrlength 22<br />
dst hdrlength != 33-45<br />
dst hdrlength { 33, 55, 67, 88 }<br />
</source><br />
|}<br />
<br />
<br />
==== Frag ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|frag match<br />
|-<br />
| ''nexthdr <proto>''<br />
| Next protocol header<br />
|<source lang="bash"><br />
frag nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp, icmp}<br />
frag nexthdr 6<br />
frag nexthdr != 50-51<br />
</source><br />
|-<br />
| ''reserved <value>''<br />
| <br />
|<source lang="bash"><br />
frag reserved 22<br />
frag reserved != 33-45<br />
frag reserved { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''frag-off <value>''<br />
| <br />
|<source lang="bash"><br />
frag frag-off 22<br />
frag frag-off != 33-45<br />
frag frag-off { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''more-fragments <value>''<br />
| <br />
|<source lang="bash"><br />
frag more-fragments 0<br />
frag more-fragments 0<br />
</source><br />
|-<br />
| ''id <value>''<br />
| <br />
|<source lang="bash"><br />
frag id 1<br />
frag id 33-45<br />
</source><br />
|}<br />
<br />
<br />
==== Hbh ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|hbh match<br />
|-<br />
| ''nexthdr <proto>''<br />
| Next protocol header<br />
|<source lang="bash"><br />
hbh nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, icmpv6}<br />
hbh nexthdr 22<br />
hbh nexthdr != 33-45<br />
</source><br />
|-<br />
| ''hdrlength <length>''<br />
| Header Length<br />
|<source lang="bash"><br />
hbh hdrlength 22<br />
hbh hdrlength != 33-45<br />
hbh hdrlength { 33, 55, 67, 88 }<br />
</source><br />
|}<br />
<br />
<br />
==== Mh ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|mh match<br />
|-<br />
| ''nexthdr <proto>''<br />
| Next protocol header<br />
|<source lang="bash"><br />
mh nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp }<br />
mh nexthdr 22<br />
mh nexthdr != 33-45<br />
</source><br />
|-<br />
| ''hdrlength <length>''<br />
| Header Length<br />
|<source lang="bash"><br />
mh hdrlength 22<br />
mh hdrlength != 33-45<br />
mh hdrlength { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''type <type>''<br />
| <br />
|<source lang="bash"><br />
mh type {binding-refresh-request, home-test-init, careof-test-init, home-test, careof-test, binding-update, binding-acknowledgement, binding-error, fast-binding-update, fast-binding-acknowledgement, fast-binding-advertisement, experimental-mobility-header, home-agent-switch-message}<br />
mh type home-agent-switch-message<br />
mh type != home-agent-switch-message<br />
</source><br />
|-<br />
| ''reserved <value>''<br />
| <br />
|<source lang="bash"><br />
mh reserved 22<br />
mh reserved != 33-45<br />
mh reserved { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''checksum <value>''<br />
| <br />
|<source lang="bash"><br />
mh checksum 22<br />
mh checksum != 33-45<br />
mh checksum { 33, 55, 67, 88}<br />
</source><br />
|}<br />
<br />
<br />
==== Rt ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|rt match<br />
|-<br />
| ''nexthdr <proto>''<br />
| Next protocol header<br />
|<source lang="bash"><br />
rt nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp }<br />
rt nexthdr 22<br />
rt nexthdr != 33-45<br />
</source><br />
|-<br />
| ''hdrlength <length>''<br />
| Header Length<br />
|<source lang="bash"><br />
rt hdrlength 22<br />
rt hdrlength != 33-45<br />
rt hdrlength { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''type <type>''<br />
| <br />
|<source lang="bash"><br />
rt type 22<br />
rt type != 33-45<br />
rt type { 33, 55, 67, 88 }<br />
</source><br />
|-<br />
| ''seg-left <value>''<br />
| <br />
|<source lang="bash"><br />
rt seg-left 22<br />
rt seg-left != 33-45<br />
rt seg-left { 33, 55, 67, 88}<br />
</source><br />
|}<br />
<br />
<br />
==== Vlan ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|vlan match<br />
|-<br />
| ''id <value>''<br />
| Vlan tag ID<br />
|<source lang="bash"><br />
vlan id 4094<br />
vlan id 0<br />
</source><br />
|-<br />
| ''cfi <value>''<br />
| <br />
|<source lang="bash"><br />
vlan cfi 0<br />
vlan cfi 1<br />
</source><br />
|-<br />
| ''pcp <value>''<br />
| <br />
|<source lang="bash"><br />
vlan pcp 7<br />
vlan pcp 3<br />
</source><br />
|}<br />
<br />
<br />
==== Arp ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|arp match<br />
|-<br />
| ''ptype <value>''<br />
| Payload type<br />
|<source lang="bash"><br />
arp ptype 0x0800<br />
</source><br />
|-<br />
| ''htype <value>''<br />
| Header type<br />
|<source lang="bash"><br />
arp htype 1<br />
arp htype != 33-45<br />
arp htype { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''hlen <length>''<br />
| Header Length<br />
|<source lang="bash"><br />
arp hlen 1<br />
arp hlen != 33-45<br />
arp hlen { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''plen <length>''<br />
| Payload length<br />
|<source lang="bash"><br />
arp plen 1<br />
arp plen != 33-45<br />
arp plen { 33, 55, 67, 88}<br />
</source><br />
|-<br />
| ''operation <value>''<br />
| <br />
|<source lang="bash"><br />
arp operation {nak, inreply, inrequest, rreply, rrequest, reply, request}<br />
</source><br />
|}<br />
<br />
<br />
==== Ct ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|ct match<br />
|-<br />
| ''state <state>''<br />
| State of the connection<br />
|<source lang="bash"><br />
ct state { new, established, related, untracked }<br />
ct state != related<br />
ct state established<br />
ct state 8<br />
</source><br />
|-<br />
| ''direction <value>''<br />
| Direction of the packet relative to the connection<br />
|<source lang="bash"><br />
ct direction original<br />
ct direction != original<br />
ct direction {reply, original}<br />
</source><br />
|-<br />
| ''status <status>''<br />
| Status of the connection<br />
|<source lang="bash"><br />
ct status expected<br />
ct status != expected<br />
ct status {expected,seen-reply,assured,confirmed,snat,dnat,dying}<br />
</source><br />
|-<br />
| ''mark [set] <mark>''<br />
| Mark of the connection<br />
|<source lang="bash"><br />
ct mark 0<br />
ct mark or 0x23 == 0x11<br />
ct mark or 0x3 != 0x1<br />
ct mark and 0x23 == 0x11<br />
ct mark and 0x3 != 0x1<br />
ct mark xor 0x23 == 0x11<br />
ct mark xor 0x3 != 0x1<br />
ct mark 0x00000032<br />
ct mark != 0x00000032<br />
ct mark 0x00000032-0x00000045<br />
ct mark != 0x00000032-0x00000045<br />
ct mark {0x32, 0x2222, 0x42de3}<br />
ct mark {0x32-0x2222, 0x4444-0x42de3}<br />
ct mark set 0x11 xor 0x1331<br />
ct mark set 0x11333 and 0x11<br />
ct mark set 0x12 or 0x11<br />
ct mark set 0x11<br />
ct mark set mark<br />
ct mark set mark map { 1 : 10, 2 : 20, 3 : 30 }<br />
</source><br />
|-<br />
| ''expiration <time>''<br />
| Connection expiration time<br />
|<source lang="bash"><br />
ct expiration 30<br />
ct expiration 30s<br />
ct expiration != 233<br />
ct expiration != 3m53s<br />
ct expiration 33-45<br />
ct expiration 33s-45s<br />
ct expiration != 33-45<br />
ct expiration != 33s-45s<br />
ct expiration {33, 55, 67, 88}<br />
ct expiration { 1m7s, 33s, 55s, 1m28s}<br />
</source><br />
|-<br />
| ''helper "<helper>"''<br />
| Helper associated with the connection<br />
|<source lang="bash"><br />
ct helper "ftp"<br />
</source><br />
|-<br />
| | ''[original | reply] bytes <value>''<br />
| <br />
|<source lang="bash"><br />
ct original bytes > 100000<br />
ct bytes > 100000<br />
</source><br />
|-<br />
| | ''[original | reply] packets <value>''<br />
| <br />
|<source lang="bash"><br />
ct reply packets < 100<br />
</source><br />
|-<br />
| | ''[original | reply] saddr <ip source address>''<br />
| <br />
|<source lang="bash"><br />
ct original saddr 192.168.0.1<br />
ct reply saddr 192.168.0.1<br />
ct original saddr 192.168.1.0/24<br />
ct reply saddr 192.168.1.0/24<br />
</source><br />
|-<br />
| | ''[original | reply] daddr <ip destination address>''<br />
| <br />
|<source lang="bash"><br />
ct original daddr 192.168.0.1<br />
ct reply daddr 192.168.0.1<br />
ct original daddr 192.168.1.0/24<br />
ct reply daddr 192.168.1.0/24<br />
</source><br />
|-<br />
| | ''[original | reply] l3proto <protocol>''<br />
| <br />
|<source lang="bash"><br />
ct original l3proto ipv4<br />
</source><br />
|-<br />
| | ''[original | reply] protocol <protocol>''<br />
| <br />
|<source lang="bash"><br />
ct original protocol 6<br />
</source><br />
|-<br />
| | ''[original | reply] proto-dst <port>''<br />
| <br />
|<source lang="bash"><br />
ct original proto-dst 22<br />
</source><br />
|-<br />
| | ''[original | reply] proto-src <port>''<br />
| <br />
|<source lang="bash"><br />
ct reply proto-src 53<br />
</source><br />
|}<br />
<br />
<br />
==== Meta ====<br />
<br />
[[Matching packet metainformation|''meta'']] matches packet by metainformation.<br />
<br />
{| class="wikitable"<br />
!colspan="6"|meta match<br />
|-<br />
| ''iifname <input interface name>''<br />
| Input interface name<br />
|<source lang="bash"><br />
meta iifname "eth0"<br />
meta iifname != "eth0"<br />
meta iifname {"eth0", "lo"}<br />
meta iifname "eth*"<br />
</source><br />
|-<br />
| ''oifname <output interface name>''<br />
| Output interface name<br />
|<source lang="bash"><br />
meta oifname "eth0"<br />
meta oifname != "eth0"<br />
meta oifname {"eth0", "lo"}<br />
meta oifname "eth*"<br />
</source><br />
|-<br />
| ''iif <input interface index>''<br />
| Input interface index<br />
|<source lang="bash"><br />
meta iif eth0<br />
meta iif != eth0<br />
</source><br />
|-<br />
| ''oif <output interface index>''<br />
| Output interface index<br />
|<source lang="bash"><br />
meta oif lo<br />
meta oif != lo<br />
meta oif {eth0, lo}<br />
</source><br />
|-<br />
| ''iiftype <input interface type>''<br />
| Input interface type<br />
|<source lang="bash"><br />
meta iiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre}<br />
meta iiftype != ether<br />
meta iiftype ether<br />
</source><br />
|-<br />
| ''oiftype <output interface type>''<br />
| Output interface hardware type<br />
|<source lang="bash"><br />
meta oiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre}<br />
meta oiftype != ether<br />
meta oiftype ether<br />
</source><br />
|-<br />
| ''length <length>''<br />
| Length of the packet in bytes<br />
|<source lang="bash"><br />
meta length 1000<br />
meta length != 1000<br />
meta length > 1000<br />
meta length 33-45<br />
meta length != 33-45<br />
meta length { 33, 55, 67, 88 }<br />
meta length { 33-55, 67-88 }<br />
</source><br />
|-<br />
| ''protocol <protocol>''<br />
| ethertype protocol<br />
|<source lang="bash"><br />
meta protocol ip<br />
meta protocol != ip<br />
meta protocol { ip, arp, ip6, vlan }<br />
</source><br />
|-<br />
| ''nfproto <protocol>''<br />
| <br />
|<source lang="bash"><br />
meta nfproto ipv4<br />
meta nfproto != ipv6<br />
meta nfproto { ipv4, ipv6 }<br />
</source><br />
|-<br />
| ''l4proto <protocol>''<br />
| <br />
|<source lang="bash"><br />
meta l4proto 22<br />
meta l4proto != 233<br />
meta l4proto 33-45<br />
meta l4proto { 33, 55, 67, 88 }<br />
meta l4proto { 33-55 }<br />
</source><br />
|-<br />
| ''mark [set] <mark>''<br />
| Packet mark<br />
|<source lang="bash"><br />
meta mark 0x4<br />
meta mark 0x00000032<br />
meta mark and 0x03 == 0x01<br />
meta mark and 0x03 != 0x01<br />
meta mark != 0x10<br />
meta mark or 0x03 == 0x01<br />
meta mark or 0x03 != 0x01<br />
meta mark xor 0x03 == 0x01<br />
meta mark xor 0x03 != 0x01<br />
meta mark set 0xffffffc8 xor 0x16<br />
meta mark set 0x16 and 0x16<br />
meta mark set 0xffffffe9 or 0x16<br />
meta mark set 0xffffffde and 0x16<br />
meta mark set 0x32 or 0xfffff<br />
meta mark set 0xfffe xor 0x16<br />
</source><br />
|-<br />
| ''skuid <user id>''<br />
| UID associated with originating socket<br />
|<source lang="bash"><br />
meta skuid {bin, root, daemon}<br />
meta skuid root<br />
meta skuid != root<br />
meta skuid lt 3000<br />
meta skuid gt 3000<br />
meta skuid eq 3000<br />
meta skuid 3001-3005<br />
meta skuid != 2001-2005<br />
meta skuid { 2001-2005 }<br />
</source><br />
|-<br />
| ''skgid <group id>''<br />
| GID associated with originating socket<br />
|<source lang="bash"><br />
meta skgid {bin, root, daemon}<br />
meta skgid root<br />
meta skgid != root<br />
meta skgid lt 3000<br />
meta skgid gt 3000<br />
meta skgid eq 3000<br />
meta skgid 3001-3005<br />
meta skgid != 2001-2005<br />
meta skgid { 2001-2005 }<br />
</source><br />
|-<br />
| ''rtclassid <class>''<br />
| Routing realm<br />
|<source lang="bash"><br />
meta rtclassid cosmos<br />
</source><br />
|-<br />
| ''pkttype <type>''<br />
| Packet type<br />
|<source lang="bash"><br />
meta pkttype broadcast<br />
meta pkttype != broadcast<br />
meta pkttype { broadcast, unicast, multicast}<br />
</source><br />
|-<br />
| ''cpu <cpu index>''<br />
| CPU ID<br />
|<source lang="bash"><br />
meta cpu 1<br />
meta cpu != 1<br />
meta cpu 1-3<br />
meta cpu != 1-2<br />
meta cpu { 2,3 }<br />
meta cpu { 2-3, 5-7 }<br />
</source><br />
|-<br />
| ''iifgroup <input group>''<br />
| Input interface group<br />
|<source lang="bash"><br />
meta iifgroup 0<br />
meta iifgroup != 0<br />
meta iifgroup default<br />
meta iifgroup != default<br />
meta iifgroup {default}<br />
meta iifgroup { 11,33 }<br />
meta iifgroup {11-33}<br />
</source><br />
|-<br />
| ''oifgroup <group>''<br />
| Output interface group<br />
|<source lang="bash"><br />
meta oifgroup 0<br />
meta oifgroup != 0<br />
meta oifgroup default<br />
meta oifgroup != default<br />
meta oifgroup {default}<br />
meta oifgroup { 11,33 }<br />
meta oifgroup {11-33}<br />
</source><br />
|-<br />
| ''cgroup <group>''<br />
| <br />
|<source lang="bash"><br />
meta cgroup 1048577<br />
meta cgroup != 1048577<br />
meta cgroup { 1048577, 1048578 }<br />
meta cgroup 1048577-1048578<br />
meta cgroup != 1048577-1048578<br />
meta cgroup {1048577-1048578}<br />
</source><br />
|}<br />
<br />
<br />
=== Statements ===<br />
<br />
'''statement''' is the action performed when the packet match the rule. It could be ''terminal'' and ''non-terminal''. In a certain rule we can consider several non-terminal statements but only a single terminal statement.<br />
<br />
==== Verdict statements ====<br />
<br />
The '''verdict statement''' alters control flow in the ruleset and issues policy decisions for packets. The valid verdict statements are:<br />
<br />
* ''accept'': Accept the packet and stop the remain rules evaluation.<br />
* ''drop'': Drop the packet and stop the remain rules evaluation.<br />
* ''queue'': Queue the packet to userspace and stop the remain rules evaluation.<br />
* ''continue'': Continue the ruleset evaluation with the next rule.<br />
* ''return'': Return from the current chain and continue at the next rule of the last chain. In a base chain it is equivalent to accept<br />
* ''jump <chain>'': Continue at the first rule of <chain>. It will continue at the next rule after a return statement is issued<br />
* ''goto <chain>'': Similar to jump, but after the new chain the evaluation will continue at the last chain instead of the one containing the goto statement<br />
<br />
==== Log ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|log statement<br />
|-<br />
| ''level [over] <value> <unit> [burst <value> <unit>]''<br />
| Log level<br />
|<source lang="bash"><br />
log<br />
log level emerg<br />
log level alert<br />
log level crit<br />
log level err<br />
log level warn<br />
log level notice<br />
log level info<br />
log level debug<br />
</source><br />
|-<br />
| ''group <value> [queue-threshold <value>] [snaplen <value>] [prefix "<prefix>"]''<br />
| <br />
|<source lang="bash"><br />
log prefix aaaaa-aaaaaa group 2 snaplen 33<br />
log group 2 queue-threshold 2<br />
log group 2 snaplen 33<br />
</source><br />
|}<br />
<br />
<br />
==== Reject ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|reject statement<br />
|-<br />
| ''with <protocol> type <type>''<br />
| <br />
|<source lang="bash"><br />
reject<br />
reject with icmp type host-unreachable<br />
reject with icmp type net-unreachable<br />
reject with icmp type prot-unreachable<br />
reject with icmp type port-unreachable<br />
reject with icmp type net-prohibited<br />
reject with icmp type host-prohibited<br />
reject with icmp type admin-prohibited<br />
reject with icmpv6 type no-route<br />
reject with icmpv6 type admin-prohibited<br />
reject with icmpv6 type addr-unreachable<br />
reject with icmpv6 type port-unreachable<br />
ip protocol tcp reject with tcp reset<br />
reject with icmpx type host-unreachable<br />
reject with icmpx type no-route<br />
reject with icmpx type admin-prohibited<br />
reject with icmpx type port-unreachable<br />
</source><br />
|}<br />
<br />
<br />
==== Counter ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|counter statement<br />
|-<br />
| ''packets <packets> bytes <bytes>''<br />
| <br />
|<source lang="bash"><br />
counter<br />
counter packets 0 bytes 0<br />
</source><br />
|}<br />
<br />
<br />
==== Limit ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|limit statement<br />
|-<br />
| ''rate [over] <value> <unit> [burst <value> <unit>]''<br />
| Rate limit<br />
|<source lang="bash"><br />
limit rate 400/minute<br />
limit rate 400/hour<br />
limit rate over 40/day<br />
limit rate over 400/week<br />
limit rate over 1023/second burst 10 packets<br />
limit rate 1025 kbytes/second<br />
limit rate 1023000 mbytes/second<br />
limit rate 1025 bytes/second burst 512 bytes<br />
limit rate 1025 kbytes/second burst 1023 kbytes<br />
limit rate 1025 mbytes/second burst 1025 kbytes<br />
limit rate 1025000 mbytes/second burst 1023 mbytes<br />
</source><br />
|}<br />
<br />
==== Nat ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|nat statement<br />
|-<br />
| ''dnat <destination address>''<br />
| Destination address translation<br />
|<source lang="bash"><br />
dnat 192.168.3.2<br />
dnat ct mark map { 0x00000014 : 1.2.3.4}<br />
</source><br />
|-<br />
| ''snat <ip source address>''<br />
| Source address translation<br />
|<source lang="bash"><br />
snat 192.168.3.2<br />
snat 2001:838:35f:1::-2001:838:35f:2:::100<br />
</source><br />
|-<br />
| ''masquerade [<type>] [to :<port>]''<br />
| Masquerade<br />
|<source lang="bash"><br />
masquerade<br />
masquerade persistent,fully-random,random<br />
masquerade to :1024<br />
masquerade to :1024-2048<br />
</source><br />
|}<br />
<br />
==== Queue ====<br />
<br />
{| class="wikitable"<br />
!colspan="6"|queue statement<br />
|-<br />
| ''num <value> <scheduler>''<br />
| <br />
|<source lang="bash"><br />
queue<br />
queue num 2<br />
queue num 2-3<br />
queue num 4-5 fanout bypass<br />
queue num 4-5 fanout<br />
queue num 4-5 bypass<br />
</source><br />
|}<br />
<br />
== Extras ==<br />
<br />
=== Export Configuration ===<br />
<br />
<source lang="bash"><br />
% nft export (xml | json)<br />
</source><br />
<br />
=== Monitor Events ===<br />
<br />
Monitor events from Netlink creating filters.<br />
<br />
<source lang="bash"><br />
% nft monitor [new | destroy] [tables | chains | sets | rules | elements] [xml | json]<br />
</source><br />
<br />
<br />
= Nft scripting =<br />
<br />
== List ruleset ==<br />
<br />
<source lang="bash"><br />
% nft list ruleset<br />
</source><br />
<br />
== Flush ruleset ==<br />
<br />
<source lang="bash"><br />
% nft flush ruleset<br />
</source><br />
<br />
== Load ruleset ==<br />
<br />
Create a command batch file and load it with the nft interpreter,<br />
<br />
<source lang="bash"><br />
% echo "flush ruleset" > /etc/nftables.rules<br />
% echo "add table filter" >> /etc/nftables.rules<br />
% echo "add chain filter input" >> /etc/nftables.rules<br />
% echo "add rule filter input meta iifname lo accept" >> /etc/nftables.rules<br />
% nft -f /etc/nftables.rules<br />
</source><br />
<br />
or create an executable nft script file,<br />
<br />
<source lang="bash"><br />
% cat << EOF > /etc/nftables.rules<br />
> #!/usr/local/sbin/nft -f<br />
> flush ruleset<br />
> add table filter<br />
> add chain filter input<br />
> add rule filter input meta iifname lo accept<br />
> EOF<br />
% chmod u+x /etc/nftables.rules<br />
% /etc/nftables.rules<br />
</source><br />
<br />
or create an executable nft script file from an already created ruleset,<br />
<br />
<source lang="bash"><br />
% nft list ruleset > /etc/nftables.rules<br />
% nft flush ruleset<br />
% nft -f /etc/nftables.rules<br />
</source><br />
<br />
<br />
= Examples =<br />
<br />
== Simple IP/IPv6 Firewall ==<br />
<br />
<source lang="bash"><br />
flush ruleset<br />
<br />
table firewall {<br />
chain incoming {<br />
type filter hook input priority 0; policy drop;<br />
<br />
# established/related connections<br />
ct state established,related accept<br />
<br />
# loopback interface<br />
iifname lo accept<br />
<br />
# icmp<br />
icmp type echo-request accept<br />
<br />
# open tcp ports: sshd (22), httpd (80)<br />
tcp dport {ssh, http} accept<br />
}<br />
}<br />
<br />
table ip6 firewall {<br />
chain incoming {<br />
type filter hook input priority 0; policy drop;<br />
<br />
# established/related connections<br />
ct state established,related accept<br />
<br />
# invalid connections<br />
ct state invalid drop<br />
<br />
# loopback interface<br />
iifname lo accept<br />
<br />
# icmp<br />
# routers may also want: mld-listener-query, nd-router-solicit<br />
icmpv6 type {echo-request,nd-neighbor-solicit} accept<br />
<br />
# open tcp ports: sshd (22), httpd (80)<br />
tcp dport {ssh, http} accept<br />
}<br />
}<br />
</source></div>Duncanhttp://wiki.nftables.org/wiki-nftables/index.php?title=Building_rules_through_expressions&diff=164Building rules through expressions2017-08-15T21:54:36Z<p>Duncan: Inserted missing "equal" rule; changed "non equal" to "not equal"; italicised equal and not equal to match other rules;use "which stands for" throughout</p>
<hr />
<div>''nftables'' provides the following built-in operations:<br />
<br />
* '''eq''' which stands for ''equal''. Alternatively you can use '''=='''.<br />
* '''ne''' which stands for ''not equal''. Alternatively you can use '''!='''.<br />
* '''lt''' which stands for ''less than''. Alternatively you can use '''<'''.<br />
* '''gt''' which stands for ''greater than''. Alternatively you can use '''>'''.<br />
* '''le''' which stands for ''less than or equal to''. Alternatively you can use '''<='''.<br />
* '''ge''' which stands for ''greater than or equal to''. Alternatively you can use '''>='''.<br />
<br />
'''Beware''': if you use the symbols '''<''' and '''>''' from the shell since it will interpret those as the standard input and output redirection respectively. You will need to escape them, eg. '''\<'''.<br />
<br />
The following example shows how to match all incoming traffic ''not'' coming to port TCP/22.<br />
<br />
<source lang="bash"><br />
nft add rule filter input tcp dport != 22<br />
</source><br />
<br />
Similarly, you can also match traffic coming to high ports with the following command:<br />
<br />
<source lang="bash"><br />
nft add rule filter input tcp dport >= 1024<br />
</source></div>Duncan