Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

6.4. Using sets in nftables commands

The nftables framework natively supports sets. You can use sets, for example, if a rule should match multiple IP addresses, port numbers, interfaces, or any other match criteria.

6.4.1. Using anonymous sets in nftables

An anonymous set contain comma-separated values enclosed in curly brackets, such as { 22, 80, 443 }, that you use directly in a rule. You can also use anonymous sets also for IP addresses or any other match criteria.
The drawback of anonymous sets is that if you want to change the set, you must replace the rule. For a dynamic solution, use named sets as described in Section 6.4.2, “Using named sets in nftables”.

Prerequisites

  • The example_chain chain and the example_table table in the inet family exists.

Procedure 6.13. Using anonymous sets in nftables

  1. For example, to add a rule to example_chain in example_table that allows incoming traffic to port 22, 80, and 443:
    # nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept
  2. Optionally, display all chains and their rules in example_table:
    # nft list table inet example_table
    table inet example_table {
      chain example_chain {
        type filter hook input priority filter; policy accept;
        tcp dport { ssh, http, https } accept
      }
    }
    

6.4.2. Using named sets in nftables

The nftables framework supports mutable named sets. A named set is a list or range of elements that you can use in multiple rules within a table. Another benefit over anonymous sets is that you can update a named set without replacing the rules that use the set.
When you create a named set, you must specify the type of elements the set contains. You can set the following types:
  • ipv4_addr for a set that contains IPv4 addresses or ranges, such as 192.0.2.1 or 192.0.2.0/24.
  • ipv6_addr for a set that contains IPv6 addresses or ranges, such as 2001:db8:1::1 or 2001:db8:1::1/64.
  • ether_addrfor a set that contains a list of media access control (MAC) addresses, such as 52:54:00:6b:66:42.
  • inet_proto for a set that contains a list of Internet protocol types, such as tcp.
  • inet_service for a set that contains a list of Internet services, such as ssh.
  • mark for a set that contains a list of packet marks. Packet marks can be any positive 32-bit integer value (0 to 2147483647).

Prerequisites

  • The example_chain chain and the example_table table exists.

Procedure 6.14. Using named sets in nftables

  1. Create an empty set. The following examples create a set for IPv4 addresses:

    1. To create a set that can store multiple individual IPv4 addresses:
      # nft add set inet example_table example_set { type ipv4_addr \; }
    2. To create a set that can store IPv4 address ranges:
      # nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }

    Important

    To avoid that the shell interprets the semicolons as the end of the command, you must escape the semicolons with a backslash.
  2. Optionally, create rules that use the set. For example, the following command adds a rule to the example_chain in the example_table that will drop all packets from IPv4 addresses in example_set.
    # nft add rule inet example_table example_chain ip saddr @example_set drop
    Because example_set is still empty, the rule has currently no effect.
  3. Add IPv4 addresses to example_set:

    1. If you create a set that stores individual IPv4 addresses, enter:
      # nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }
    2. If you create a set that stores IPv4 ranges, enter:
      # nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }
    When you specify an IP address range, you can alternatively use the Classless Inter-Domain Routing (CIDR) notation, such as 192.0.2.0/24 in the above example.