Docs / Networking / How to Use nftables as a Modern Firewall

How to Use nftables as a Modern Firewall

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 252 views · 2 min read

nftables is the successor to iptables, providing a unified framework for packet filtering, NAT, and traffic classification. It offers better performance, simpler syntax, and a single tool to replace iptables, ip6tables, arptables, and ebtables.

Why nftables?

  • Single framework for IPv4, IPv6, ARP, and bridge filtering
  • Better performance with atomic rule updates
  • More expressive syntax with variables and includes
  • Built into modern kernels (3.13+, default in Debian 10+)

Basic nftables Configuration

# /etc/nftables.conf
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # Allow established connections
        ct state established,related accept

        # Allow loopback
        iif lo accept

        # Allow ICMP
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # Allow SSH
        tcp dport 22 accept

        # Allow HTTP and HTTPS
        tcp dport { 80, 443 } accept
    }

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

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

# Apply configuration
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables

Common Operations

# List all rules
sudo nft list ruleset

# Add a rule
sudo nft add rule inet filter input tcp dport 8080 accept

# Insert a rule at the beginning
sudo nft insert rule inet filter input tcp dport 8080 accept

# Delete a rule (by handle)
sudo nft -a list ruleset  # Show handles
sudo nft delete rule inet filter input handle 10

# Flush all rules
sudo nft flush ruleset

Rate Limiting

# Rate limit SSH connections
table inet filter {
    chain input {
        tcp dport 22 ct state new meter ssh_meter { ip saddr limit rate 3/minute } accept
        tcp dport 22 ct state new drop
    }
}

NAT with nftables

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100;
        oifname "eth0" masquerade
    }

    chain prerouting {
        type nat hook prerouting priority -100;
        tcp dport 8080 dnat to 10.0.0.5:80
    }
}

Sets and Maps

# Create a set of allowed IPs
table inet filter {
    set allowed_ips {
        type ipv4_addr
        elements = { 203.0.113.1, 203.0.113.2, 198.51.100.0/24 }
    }

    chain input {
        ip saddr @allowed_ips tcp dport 22 accept
    }
}

Migration from iptables

# Convert existing iptables rules to nftables
sudo iptables-save > /tmp/iptables.rules
sudo iptables-restore-translate -f /tmp/iptables.rules > /tmp/nftables.rules
sudo nft -f /tmp/nftables.rules

Was this article helpful?