About Rules

You can add rules to chains in a table. Rules are made up of instructions that match packets based on various criteria and apply actions such as accept, drop, reject, and so on. These instructions include elements such as:
  • Sets, which are collections of elements used for the matching.
  • Expressions, which are building blocks for rules that define how packets are matched or manipulated. Examples include:
    • Protocol-specific matches (for example, ip, ip6, tcp, udp).
    • Address matching (saddr, daddr).
    • Port matching (sport, dport).
    • Network interface matches (iifname, oifname).
  • Maps, which are similar to sets but can map one value to another. Maps are used for more complex matching or transformation scenarios.
  • Verdict maps, which can change verdicts based on packet content, enable more dynamic policy decisions.
  • Counters, which track the number of packets matching a rule and display when running a list nft command that includes the rule. Counters are a useful way to test whether a rule is working.
  • Quotas, which limit the amount of data that can pass through a rule before an action changes (for example, from accept to drop).
  • Flowtables, which allows fast path packet forwarding, improving performance by bypassing regular packet processing for certain traffic.
  • Statements, which includes operations such as log, reject, jump, goto which change packet handling behavior.

Rules added to a chain are evaluated from top to bottom and from left to right.

For more information about configuring these instructions, see the nft(8) manual page.

Creating Rules - Examples

This section includes some common example of rules created within chains.

Allow local traffic

The following command creates a rule in mytable within mychain for the inet family that allows local traffic to enter through the loopback interface (iff lo):
sudo nft add rule inet mytable mychain iif lo accept

Allow incoming traffic for an existing connection or related to an existing connection

This command adds a rule to the mytable's mychain chain that accepts all incoming traffic that are part of or related to an existing connection:
sudo nft add rule inet mytable mychain ct state established, related accept
In the previous example,
  • ct is a connection tracking helper for IPv4, IPv6, or inet which is part of the nf_conntrack module. This module is typically loaded by default on most systems. You can list the state of all connections to the system using the following command:
    sudo cat /proc/net/nf_conntrack
    Possible connection states are:
    • NEW: The packet has started a new connection, or is associated with a connection that hasn't received and sent packets.
    • ESTABLISHED: The packet is associated with a connection which has received and sent packets.
    • RELATED: The packet is starting a new connection, but is associated with an existing connection.
    • INVALID: The packet is associated with no known connection.
  • state established, related indicates that the command applies only to connections in the ESTABLISHED or RELATED state.
  • accept indicates that any packet with the appropriate state can be accepted.

This is a common rule in firewall configurations to ensure that responses to outgoing traffic are allowed back in, enabling normal operations of network services such as web browsing, SSH connectivity, and so on, without needing to explicitly open all ports for incoming connections.

Allow incoming SSH traffic

The following adds a rule to the mytable's mychain chain that accepts all incoming TCP traffic on destination port 22.
sudo nft add rule inet mytable mychain tcp dport 22 accept

This port is typically used for SSH traffic and assumes that the SSH daemon is setup and running on the system.

Restricting all IPv4 and IPv6 traffic (Panic button)

The following adds a rule to the mytable table that drops all incoming and outgoing IPv4 and IPv6 and acts as a kind of panic button.
sudo nft add rule inet mytable drop