Difference between revisions of "Sets"

From nftables wiki
Jump to navigation Jump to search
m (cut and paste part of Eric Leblond to anonymous sets)
(7 intermediate revisions by 2 users not shown)
Line 18: Line 18:


This rule above catches all traffic going to TCP ports 22 and 23, in case of matching the counters are updated.
This rule above catches all traffic going to TCP ports 22 and 23, in case of matching the counters are updated.
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:
<source lang="bash">
ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
</source>
Which can be expressed in ''nftables'' with a couple of rules that provide a set:
<source lang="bash">
% nft add rule ip6 filter input tcp dport {telnet, http, https} accept
% nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept
</source>


= Named sets =
= Named sets =
Line 27: Line 44:
</source>
</source>


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.
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.


<source lang="bash">
<source lang="bash">
Line 39: Line 56:
% nft add rule ip input ip saddr @blackhole drop
% nft add rule ip input ip saddr @blackhole drop
</source>
</source>
The supported data types currently are:
* ''ipv4_addr'': IPv4 address
* ''ipv6_addr'': IPv6 address.
* ''ether_addr'': Ethernet address.
* ''inet_proto'': Inet protocol type.
* ''inet_service'': Internet service (read tcp port for example)
* ''mark'': Mark type.


Named sets can be updated anytime, so you can add and delete element from them.
Named sets can be updated anytime, so you can add and delete element from them.


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:
<source lang="bash">
ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
</source>
Which can be expressed in ''nftables'' with a couple of rules that provide a set:
<source lang="bash">
% nft add rule ip6 filter input tcp dport {telnet, http, https} accept
% nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept
</source>


= Named sets specifications =
= Named sets specifications =
Line 72: Line 64:
Sets specifications are:
Sets specifications are:


* '''type''', is obrigatory and determines the data type of the set elements. Supported data types currently are:
* '''type''', is obligatory and determines the data type of the set elements. Supported data types currently are:
** ''ipv4_addr'': IPv4 address
** ''ipv4_addr'': IPv4 address
** ''ipv6_addr'': IPv6 address.
** ''ipv6_addr'': IPv6 address.
Line 80: Line 72:
** ''mark'': Mark type.
** ''mark'': Mark type.


* '''timeout''', it determines how long an element stays in the set. The time string respects the format: ''"v<small>1</small>dv<small>2</small>hv<small>3</small>mv<small>4</small>s"'':
* '''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"'':


<source lang="bash">
<source lang="bash">
Line 87: Line 79:
</source>
</source>


These commands create a table named ''filter'' and add a set to it, where elements are deleted after 3 hours and 45 seconds of being added.
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.


* '''flags''', only one flag can be set at a time, the available flags are:
* '''flags''', the available flags are:
** ''constant'' - set content may not change while bound
** ''constant'' - set content may not change while bound
** ''interval'' - set contains intervals
** ''interval'' - set contains intervals
** ''timeout'' - elements can be added with a timeout
** ''timeout'' - elements can be added with a timeout


* '''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<small>1</small>dv<small>2</small>hv<small>3</small>mv<small>4</small>s"''.
Multiple flags should be separated by comma:
 
<source lang="bash">
% nft add set filter flags_set {type ipv4_addr\; flags constant, interval\;}
</source>
 
* '''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"''.


* '''elements''', initialize the set with some elements in it:
* '''elements''', initialize the set with some elements in it:
Line 102: Line 100:
</source>
</source>


This command creates a set name ''daddrs'' with elements ''1.1.1.1'', which stays in it for 10s, and ''2.2.2.2'', which stays for 30s.
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.


* '''size''', limits the maximum number of elements of the set. To create a set with maximum 2 elements type:
* '''size''', limits the maximum number of elements of the set. To create a set with maximum 2 elements type:
Line 111: Line 109:


* '''policy''', determines set selection policy. Available values are:
* '''policy''', determines set selection policy. Available values are:
** ''performance'' [default]
** ''memory''
** ''memory''
** ''performance''


= Listing named sets =
= Listing named sets =

Revision as of 13:22, 28 December 2017

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.

The set elements are internally represented using performance data structures such as hashtables and red-black trees.

Anonymous sets

Anonymous sets are those that are:

  • Bound to a rule, if the rule is removed, that set is released too.
  • They have no specific name, the kernel internally allocates an identifier.
  • They cannot be updated. So you cannot add and delete elements from it once it is bound to a rule.

The following example shows how to create a simple set.

% nft add rule filter output tcp dport { 22, 23 } counter

This rule above catches all traffic going to TCP ports 22 and 23, in case of matching the counters are updated.

Eric Leblond in his Why you will love nftables article shows a very simple example to compare iptables with nftables:

ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT

Which can be expressed in nftables with a couple of rules that provide a set:

% nft add rule ip6 filter input tcp dport {telnet, http, https} accept
% nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept

Named sets

You can create the named sets with the following command:

% nft add set filter blackhole { type ipv4_addr\;}

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.

% nft add element filter blackhole { 192.168.3.4 }
% nft add element filter blackhole { 192.168.1.4, 192.168.1.5 }

Then, you can use it from the rule:

% nft add rule ip input ip saddr @blackhole drop

Named sets can be updated anytime, so you can add and delete element from them.


Named sets specifications

Sets specifications are:

  • type, is obligatory and determines the data type of the set elements. Supported data types currently are:
    • ipv4_addr: IPv4 address
    • ipv6_addr: IPv6 address.
    • ether_addr: Ethernet address.
    • inet_proto: Inet protocol type.
    • inet_service: Internet service (read tcp port for example)
    • mark: Mark type.
  • timeout, it determines how long an element stays in the set. The time string respects the format: "v1dv2hv3mv4s":
% nft add table filter
% nft add set filter ports {type inet_service \; timeout 3h45s \;}

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.

  • flags, the available flags are:
    • constant - set content may not change while bound
    • interval - set contains intervals
    • timeout - elements can be added with a timeout

Multiple flags should be separated by comma:

% nft add set filter flags_set {type ipv4_addr\; flags constant, interval\;}
  • 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 "v1dv2hv3mv4s".
  • elements, initialize the set with some elements in it:
% nft add set filter daddrs {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}

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.

  • size, limits the maximum number of elements of the set. To create a set with maximum 2 elements type:
% nft add set filter saddrs {type ipv4_addr \; size 2 \;}
  • policy, determines set selection policy. Available values are:
    • performance [default]
    • memory

Listing named sets

You can list the content of a named set via:

% nft list set filter myset