On CentOS/RHEL, nftables isn’t just a firewall; it’s the modern replacement for iptables, offering a more structured and efficient way to manage network traffic filtering.

Let’s see nftables in action with a common scenario: allowing SSH traffic while blocking everything else.

First, we need to install nftables. It’s usually available in the default repositories.

sudo yum install nftables

Next, we enable and start the nftables service.

sudo systemctl enable nftables
sudo systemctl start nftables

Now, let’s create a basic configuration file. We’ll define a table named inet filter which handles both IPv4 and IPv6 traffic. Inside this table, we’ll create three chains: input for incoming traffic, forward for traffic passing through the server, and output for outgoing traffic. The input chain will have a default policy of drop, meaning any traffic not explicitly allowed will be blocked.

Here’s a sample configuration file, typically located at /etc/nftables.conf:

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # Allow loopback traffic
        iifname "lo" accept

        # Allow established and related connections
        ct state established,related accept

        # Allow SSH
        tcp dport 22 accept

        # Allow ICMP (ping)
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

To load this configuration, you can use the nft command:

sudo nft -f /etc/nftables.conf

You can verify the loaded ruleset with:

sudo nft list ruleset

This output will show you the tables, chains, and rules that are currently active.

The inet family is a key concept here. It’s a shortcut that tells nftables to apply the rules to both IPv4 (ip) and IPv6 (ip6) address families simultaneously. This simplifies rule management significantly, especially on systems that are dual-stacked.

The ct state established,related accept rule is crucial for stateful firewalling. ct stands for connection tracking. This rule ensures that replies to outgoing connections, or connections related to existing ones, are automatically allowed back in without needing explicit rules for each return path. It’s a fundamental part of how nftables (and iptables) maintain context about network conversations.

When you flush ruleset, you’re telling nftables to remove all existing tables, chains, and rules before applying the new configuration. This is important to prevent conflicts and ensure a clean state.

The priority 0 in the chain definitions is also significant. For the input hook, 0 is the default priority, meaning these rules are evaluated early in the packet processing path. Different priorities allow for more granular control, but for most basic firewalling, the default is sufficient.

The policy drop on the input chain is the "deny by default" principle. Any packet that doesn’t match an accept rule will be dropped by the chain’s default policy. This is a much more secure posture than a "permit by default" policy.

To make these rules persistent across reboots, ensure the nftables service is enabled and started, as we did earlier. The service will automatically load the configuration from /etc/nftables.conf on startup.

One subtle but powerful aspect of nftables is its ability to define sets and maps. For instance, you could define a set of trusted IP addresses and then use that set in a rule:

table inet filter {
    set trusted_ips {
        type ipv4_addr
        elements = { 192.168.1.10, 10.0.0.5 }
    }

    chain input {
        # ... other rules ...
        ip saddr @trusted_ips accept
    }
    # ...
}

This allows for much more dynamic and scalable rule management, especially when dealing with large numbers of IPs or ports. You can update the set without having to rewrite the entire rule, and nftables is highly optimized for set lookups.

The next step in mastering nftables involves understanding its rich set of match expressions and its powerful expression language for crafting complex filtering logic.

Want structured learning?

Take the full Nftables course →