HxHippy

nftables Modern Firewall

Configure nftables, the modern replacement for iptables with improved performance.

Last updated: 2025-01-15

nftables Firewall

nftables is the modern replacement for iptables with cleaner syntax and better performance.

Installation

# Debian/Ubuntu
sudo apt install nftables

# RHEL/CentOS
sudo dnf install nftables

# Enable service
sudo systemctl enable nftables
sudo systemctl start nftables

Key Differences from iptables

Feature iptables nftables
Tables Predefined User-defined
Syntax Multiple tools Single nft command
Atomic No Yes
Performance Good Better
IPv4/IPv6 Separate Unified

Basic Commands

# List all rules
sudo nft list ruleset

# List specific table
sudo nft list table inet filter

# Flush all rules
sudo nft flush ruleset

# Delete table
sudo nft delete table inet filter

Configuration Structure

table family name {
    chain name {
        type filter hook input priority 0;
        # rules here
    }
}

Families

  • inet - IPv4 and IPv6
  • ip - IPv4 only
  • ip6 - IPv6 only
  • arp - ARP
  • bridge - Bridging

Complete Example

/etc/nftables.conf

#!/usr/sbin/nft -f

# Flush existing rules
flush ruleset

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

        # Allow loopback
        iif lo accept

        # Allow established connections
        ct state established,related accept

        # Allow ICMP
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # Allow SSH
        tcp dport 22 accept

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

        # Log dropped packets
        log prefix "nftables-drop: " counter drop
    }

    # Forward chain
    chain forward {
        type filter hook forward priority 0; policy drop;

        ct state established,related accept
    }

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

# NAT table
table ip nat {
    chain prerouting {
        type nat hook prerouting priority -100;
    }

    chain postrouting {
        type nat hook postrouting priority 100;

        # Masquerade for outbound
        oifname "eth0" masquerade
    }
}

Rule Syntax

# Add rule to chain
sudo nft add rule inet filter input tcp dport 3306 accept

# Insert at position
sudo nft insert rule inet filter input position 2 tcp dport 8080 accept

# Delete rule by handle
sudo nft -a list chain inet filter input
sudo nft delete rule inet filter input handle 5

# Add with comment
sudo nft add rule inet filter input tcp dport 22 accept comment "SSH access"

Sets and Maps

IP Sets

table inet filter {
    set allowed_ips {
        type ipv4_addr
        elements = { 192.168.1.0/24, 10.0.0.1 }
    }

    chain input {
        ip saddr @allowed_ips accept
    }
}

Port Sets

set web_ports {
    type inet_service
    elements = { 80, 443, 8080-8090 }
}

Dictionaries (Maps)

map port_redirect {
    type inet_service : inet_service
    elements = { 80 : 8080, 443 : 8443 }
}

Rate Limiting

chain input {
    # Limit SSH to 3 per minute
    tcp dport 22 limit rate 3/minute accept

    # Limit ICMP
    icmp type echo-request limit rate 10/second accept
}

Apply and Save

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

# Validate syntax
sudo nft -c -f /etc/nftables.conf

# Save current rules
sudo nft list ruleset > /etc/nftables.conf

# Reload service
sudo systemctl reload nftables

Migrate from iptables

# Export iptables rules
sudo iptables-save > iptables.rules

# Convert to nftables
sudo iptables-restore-translate -f iptables.rules > nftables.conf

Best Practices

  1. Use inet family - Handle both IPv4 and IPv6
  2. Use sets - For multiple IPs/ports
  3. Validate first - Use -c flag
  4. Comment rules - For documentation
  5. Test in stages - Don't lock yourself out
intermediate Firewalls Updated 2025-01-15
  • nftables
  • firewall
  • linux
  • netfilter
  • packet filtering
  • iptables replacement