rss logo

Essential nftables Commands for Managing Linux Firewalls

nftables is the modern replacement for the iptables tool used to manage the Netfilter firewall framework in Linux. Below are key commands and notes to help understand how it works on a typical Linux system (example shown with Debian).

Configuration

  • OS: Debian 12
  • nftables: v1.0.6 (Lester Gooch #5)

General Information

  • Enable nftables at boot using systemctl:
root@host:~# systemctl enable nftables.service
  • Default configuration file location:
root@host:~# /etc/nftables.conf
  • Load the nftables configuration file manually:
root@host:~# nft -f /etc/nftables.conf
  • List the currently active ruleset:
root@host:~# nft list ruleset

Note: The inet family includes both ip (IPv4) and ip6 (IPv6). Use ip or ip6 explicitly if needed.

Tables

  • Create a new table:
root@host:~# nft add table inet <table_name>
  • List existing tables:
root@host:~# nft list tables
  • Delete a table:
root@host:~# nft delete table inet <table_name>
  • Flush a table (remove all rules without deleting the table):
root@host:~# nft flush table inet <table_name>

Chains

  • Create a new chain:
root@host:~# nft add chain inet <table_name> <chain_name>
  • List all chains:
root@host:~# nft list chains
  • Delete a chain:
root@host:~# nft delete chain inet <table_name> <chain_name>
  • Create an input chain for inbound traffic:
root@host:~# nft add chain inet filter INPUT { type filter hook input priority 0\; }
  • Create a forward chain for routed traffic:
root@host:~# nft add chain inet filter FORWARD { type filter hook forward priority 0\; }
  • Create an output chain for outbound traffic:
root@host:~# nft add chain inet filter OUTPUT { type filter hook output priority 0\; }
  • Create a NAT chain for masquerading (postrouting):
root@host:~# nft add chain inet filter my_masquerade '{ type nat hook postrouting priority 100; }'
  • Create a NAT chain for prerouting and port redirection:
root@host:~# nft add chain inet filter my_prerouting '{ type nat hook prerouting priority -100; }'

Rules

Create rules

  • Allow input traffic with packet counting and a comment:
root@host:~# nft add rule inet <table_name> <chain_name> counter accept comment "ALLOW INPUT"
  • Allow SSH traffic on port 22 and count packets:
root@host:~# nft add rule inet filter INPUT tcp dport 22 counter
  • Allow HTTP and HTTPS traffic in new or established states with packet counting:
root@host:~# nft add rule inet filter INPUT tcp dport {80, 443} ct state new,established counter accept

Delete rules

  • List rules with handle numbers:
root@host:~# nft -n -a list ruleset
  • Delete a rule by its handle number:
root@host:~# nft delete rule ip filter INPUT handle 38

Replace a rule

  • List current rules with handle numbers:
root@host:~# nft -n -a list ruleset
  • Replace a rule using its handle:
root@host:~# nft replace rule ip filter INPUT handle 38 iifname "eth0" ip saddr 192.168.1.12 counter drop

Insert a rule

  • Insert a rule at a specific position in the chain:
root@host:~# nft insert rule ip filter INPUT position 17 iifname "eth0" ip saddr { 192.168.1.11, 192.168.1.68, 192.168.1.118 } counter drop

NAT

Create table

  • Create a dedicated table for NAT:
root@host:~# nft add table ip NAT

Create chains

  • Create a postrouting chain for masquerading traffic:
root@host:~# nft add chain ip NAT my_masquerade '{ type nat hook postrouting priority 100; }'
  • Create a prerouting chain for port redirection:
root@host:~# nft add chain ip NAT my_prerouting '{ type nat hook prerouting priority -100; }'

Masquerading rule

  • Masquerade all outgoing traffic, except for destination addresses in 192.168.0.0/16:
root@host:~# nft add rule NAT my_masquerade ip daddr != { 192.168.0.0/16 } oifname <interface> masquerade

Prerouting rule

  • Redirect HTTPS traffic to an internal server (192.168.1.10) using DNAT:
root@host:~# nft add rule NAT my_prerouting iifname <interface> tcp dport { https } dnat to 192.168.1.10 comment "Web Server"