VOOZH about

URL: https://wiki.nftables.org/wiki-nftables/index.php/Sets

⇱ Sets - nftables wiki


Sets

From nftables wiki
Jump to navigation Jump to search

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 maps and verdict 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.

%nftaddruleipfilteroutputtcpdport{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-AINPUT-ptcp-mmultiport--dports23,80,443-jACCEPT
ip6tables-AINPUT-picmpv6--icmpv6-typeneighbor-solicitation-jACCEPT
ip6tables-AINPUT-picmpv6--icmpv6-typeecho-request-jACCEPT
ip6tables-AINPUT-picmpv6--icmpv6-typerouter-advertisement-jACCEPT
ip6tables-AINPUT-picmpv6--icmpv6-typeneighbor-advertisement-jACCEPT

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

%nftaddruleip6filterinputtcpdport{telnet,http,https}accept
%nftaddruleip6filterinputicmpv6type{nd-neighbor-solicit,echo-request,nd-router-advert,nd-neighbor-advert}accept

Named sets

You can use nft add set to create a named set. For example:

%nftaddsetipfilterblackhole{typeipv4_addr\;comment\"dropallpacketsfromthesehosts\"\;}

creates a set named blackhole. Set names must be 16 characters or less. The optional set comment attribute requires at least nftables 0.9.7 and kernel 5.10. The type keyword indicates the data type of elements to be stored in the set. In this case blackhole stores IPv4 addresses, which you can add using nft add element:

%nftaddelementipfilterblackhole{192.168.3.4}
%nftaddelementipfilterblackhole{192.168.1.4,192.168.1.5}

You can use named sets from rules, as for example:

%nftaddruleipfilterinputipsaddr@blackholedrop
%nftaddruleipfilteroutputipdaddr!=@blackholeaccept

Named sets can be updated anytime.

nftables.conf syntax

When working with nftables.conf, you can define sets in a number of ways. You can then reference those sets later on using $VARIABLE_NAME notation.

Here are some examples showing sets defined in one line, spanning multiple lines, and sets referencing other sets. The set is then used in a rule to allow incoming traffic from certain IP ranges.

defineSIMPLE_SET={192.168.1.1,192.168.1.2}

defineCDN_EDGE={
192.168.1.1,
192.168.1.2,
192.168.1.3,
10.0.0.0/8
}

defineCDN_MONITORS={
192.168.1.10,
192.168.1.20
}

defineCDN={
$CDN_EDGE,
$CDN_MONITORS
}

# Allow HTTP(S) from approved IP ranges only
tcpdport{http,https}ipsaddr$CDNaccept
udpdport{http,https}ipsaddr$CDNaccept

Named sets specifications

Sets specifications are:

  • type or typeof, is obligatory and determines the data type of the set elements.

Supported data types if using the type keyword 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.
    • ifname: Network interface name (eth0, eth1..)

The typeof keyword is available since 0.9.4 and allows you to use a high level expression, then let nftables resolve the base type for you:

tableinetmytable{
sets1{
typeofosfname
elements={"Linux"}
}
sets2{
typeofvlanid
elements={2,3,103}
}
sets3{
typeofipdaddr
elements={1.1.1.1}
}
}


  • timeout, it determines how long an element stays in the set. The time string respects the format: "v1dv2hv3mv4s":
%nftaddtableipfilter
%nftaddsetipfilterports{typeinet_service\;timeout3h45s\;}

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:

%nftaddsetipfilterflags_set{typeipv4_addr\;flagsconstant,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:
%nftaddsetipfilterdaddrs{typeipv4_addr\;flagstimeout\;elements={192.168.1.1timeout10s,192.168.1.2timeout30s}\;}

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:
%nftaddsetipfiltersaddrs{typeipv4_addr\;size2\;}
  • policy, determines set selection policy. Available values are:
    • performance [default]
    • memory
  • counter, (available since version 0.9.5) which enables a counter per element:
tableinetmytable{
sets{
typeofipsaddr
counter
elements={1.1.1.1counterpackets0bytes0,1.1.1.2counterpackets0bytes0,
1.1.1.3counterpackets0bytes0,1.1.1.4counterpackets0bytes0}
}
}
  • auto-merge, to automatic merge adjacent/overlapping set elements. This is only valid for interval sets.

For example, this origin set configuration will collapse the elements into the CIDR:

tableinetmytable{
setmyset{
typeofipsaddr
flagsinterval
auto-merge
elements={10.0.0.1,
10.0.0.2,
10.0.0.3,
10.0.0.0/8,
}
}
}

Resulting in this when you list back the ruleset, because the CIDR already contains the individual elements:

tableinetmytable{
setmyset{
typeofipsaddr
flagsinterval
auto-merge
elements={10.0.0.0/8,
}
}
}

Also, note that not using auto-merge will make such ruleset fail to load with something like:

/etc/nftables/ruleset.nft:38:21-29: Error: conflicting intervals specified
 10.0.0.1 ,
 ~~~~~~~^^^^^^^^^

Listing named sets

You can list the content of a named set via:

%nftlistsetipfiltermyset

Query for element membership in a set

You can also check if an element exists in the set from its key:

%nftgetelementipfiltermyset{1.1.1.1}

The example above checks if the IPv4 address 1.1.1.1 exists in the myset set.

Retrieved from "http://wiki.nftables.org/wiki-nftables/index.php?title=Sets&oldid=1097"

Navigation menu

Search