How to Configure nftables Firewall on RHEL 7
nftables is the modern successor to iptables, combining the functionality of iptables, ip6tables, arptables, and ebtables into a single, unified framework with a cleaner syntax, better performance, and native support for atomic rule replacement. While firewalld is the default front end on RHEL 7, nftables is available starting with RHEL 7.7 and provides a low-level alternative for administrators who want direct control over the netfilter subsystem. This guide covers installing nftables on RHEL 7, understanding its table and chain model, writing rules with the nft command, using sets and maps for efficient multi-address matching, and persisting your ruleset across reboots.
Prerequisites
- RHEL 7.7 or later (nftables is not available in earlier RHEL 7 minor releases)
- Root or
sudoaccess - An active SSH session — keep it open while testing firewall changes
- Basic familiarity with firewall concepts (tables, chains, policies)
Step 1: Install nftables
The nftables package is in the base RHEL 7 repository from version 7.7 onward:
yum install nftables -y
Verify the installation and check the version:
nft --version
Enable and start the nftables service, which will load rules from /etc/sysconfig/nftables.conf at boot:
systemctl enable nftables
systemctl start nftables
If you are transitioning from firewalld or iptables, stop those services first to avoid conflicts:
systemctl stop firewalld
systemctl disable firewalld
systemctl mask firewalld
systemctl stop iptables
systemctl disable iptables
Step 2: Understand the nftables Data Model
nftables uses a hierarchy of three objects:
- Tables — top-level containers associated with an address family (
ip,ip6,inet,arp,bridge). Theinetfamily handles both IPv4 and IPv6 in one table, which is the recommended approach for most servers. - Chains — ordered lists of rules within a table. Base chains hook into the kernel netfilter hooks (
input,output,forward,prerouting,postrouting); regular chains are called by rules usingjumporgoto. - Rules — individual match-and-verdict statements within a chain.
Step 3: View the Current Ruleset
Display all currently loaded tables, chains, and rules:
nft list ruleset
On a fresh installation the output will be empty. To list only a specific table:
nft list table inet filter
Step 4: Create a Table and Chains
Create an inet family table named filter that handles both IPv4 and IPv6 traffic:
nft add table inet filter
Add a base chain for incoming traffic with a default drop policy:
nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
Add chains for forwarded and outgoing traffic:
nft add chain inet filter forward { type filter hook forward priority 0 ; policy drop ; }
nft add chain inet filter output { type filter hook output priority 0 ; policy accept ; }
Verify the chains were created:
nft list table inet filter
Step 5: Add Rules to the Input Chain
Allow loopback traffic, which is required by many local services:
nft add rule inet filter input iif lo accept
Allow established and related connections (stateful tracking equivalent to iptables -m state):
nft add rule inet filter input ct state established,related accept
Drop invalid packets:
nft add rule inet filter input ct state invalid drop
Allow ICMP (IPv4 ping) and ICMPv6:
nft add rule inet filter input ip protocol icmp accept
nft add rule inet filter input ip6 nexthdr icmpv6 accept
Allow SSH (TCP port 22):
nft add rule inet filter input tcp dport 22 accept
Allow HTTP and HTTPS:
nft add rule inet filter input tcp dport { 80, 443 } accept
Note the curly-brace syntax — nftables supports anonymous sets directly in rules, eliminating the need for multiple identical rules for different ports.
Step 6: Add Packet Counters
nftables can attach byte and packet counters to individual rules without separate tools. Add a counter to the SSH rule for monitoring:
nft add rule inet filter input tcp dport 22 counter accept
View the counters:
nft list chain inet filter input
Output will include per-rule packet and byte counts:
table inet filter {
chain input {
...
tcp dport 22 counter packets 47 bytes 3124 accept
}
}
Step 7: Use Named Sets for Efficient Multi-Address Matching
Named sets allow you to define a collection of addresses, ports, or prefixes once and reference them in multiple rules. Create a set of trusted management IP addresses:
nft add set inet filter trusted_hosts { type ipv4_addr ; }
nft add element inet filter trusted_hosts { 10.0.0.10, 10.0.0.11, 192.168.1.5 }
Reference the set in a rule to restrict SSH to those addresses only:
nft add rule inet filter input ip saddr @trusted_hosts tcp dport 22 accept
Adding or removing addresses from the set takes effect immediately without reloading the entire ruleset:
nft add element inet filter trusted_hosts { 10.0.1.50 }
nft delete element inet filter trusted_hosts { 10.0.0.10 }
Step 8: Use Maps for Dynamic Port-to-Action Mapping
Maps associate keys with verdicts, enabling compact multi-service rules. For example, map specific ports to accept or drop:
nft add map inet filter port_verdict { type inet_service : verdict ; }
nft add element inet filter port_verdict { 22 : accept, 80 : accept, 443 : accept, 23 : drop }
nft add rule inet filter input tcp dport vmap @port_verdict
Step 9: Persist Rules in /etc/sysconfig/nftables.conf
Flush the current ruleset to a file and configure the nftables service to load it on boot:
nft list ruleset > /etc/sysconfig/nftables.conf
The nftables systemd service reads this file at startup. Verify by examining the service unit:
systemctl cat nftables
To flush all rules and reload from the file at any time:
nft flush ruleset
nft -f /etc/sysconfig/nftables.conf
For atomic rule replacement (replacing all rules in one kernel operation with no momentary gap):
nft -f /etc/sysconfig/nftables.conf
Unlike iptables, nftables applies the entire file as a transaction, so the transition between old and new rules is instantaneous.
Step 10: Delete Specific Rules
Each rule in nftables has a numeric handle. To find handles:
nft list chain inet filter input --handle
Delete a rule by its handle (e.g., handle 8):
nft delete rule inet filter input handle 8
Conclusion
nftables brings a coherent, powerful approach to Linux packet filtering on RHEL 7. The unified inet address family eliminates the need for parallel IPv4 and IPv6 rule sets, anonymous and named sets replace repetitive single-value rules, and atomic file loading via nft -f makes rule updates safe and instantaneous. While the tooling is slightly less mature than iptables on RHEL 7 and documentation is thinner, nftables is the future of Linux firewalling — Red Hat Enterprise Linux 8 and 9 use it as the default backend. Learning it on RHEL 7 now positions you well for upgrades and ensures your firewall configurations remain relevant as the ecosystem continues to move away from the legacy iptables framework.