AI Chat

nftables Firewall Configuration: Migrating from iptables on Ubuntu/Debian (2026 Guide)

Dedicated Server Graphic
Ask AI to extract steps & commands from this tutorial:

If you manage Linux bare-metal servers, you've probably noticed that iptables is being phased out in favor of nftables — and if you're running Ubuntu 24.04 LTS (Noble Numbat) or Debian 12 (Bookworm), you're already using nftables under the hood, whether you realize it or not.

This guide walks through exactly how to move your firewall rules from classic iptables syntax to native nftables, why it matters, and how to avoid the common pitfalls that trip up sysadmins during the switch.

Why iptables Is Being Replaced by nftables

nftables is the modern successor to iptables inside the Linux kernel's Netfilter subsystem. It isn't a separate firewall — it's the new engine that has quietly taken over. Since Ubuntu 20.10, the iptables command itself has been backed by nftables through a compatibility layer called iptables-nft.

The practical reasons to migrate to native nftables syntax include:

  • Unified IPv4/IPv6 rules — one rule can cover both protocol families instead of duplicating everything.
  • Better performance at scale — nftables rulesets are compiled to bytecode, which matters once you have hundreds of rules.
  • Native sets and maps — you can group IPs, ports, or interfaces into a set and reference it in one rule.
  • A single tool, nft — no more juggling iptables, ip6tables, arptables, and ebtables separately.
  • It's where the ecosystem is heading — new features and long-term support are going into nftables.

Prerequisites

  • You're running Ubuntu 20.04+ (ideally 24.04 LTS) or Debian 10+ (ideally 12 "Bookworm").
  • You have console or out-of-band access (IPMI, cloud provider console, VNC) — not just SSH. Firewall changes are the #1 way people lock themselves out of remote servers.
  • You know your current rule count and logic.
  • The nftables package is installed.

Step 1: Check What's Actually Running

On Ubuntu 24.04 and Debian 12, check whether iptables is already the nftables-backed variant:

bash

sudo update-alternatives --display iptables
                            

If it points to iptables-nft, you're already on the nftables backend under the hood — you're just using the old command syntax to talk to it.

Also check if ufw (Uncomplicated Firewall) is active, since UFW itself talks to iptables/nftables:

bash

sudo ufw status verbose
                            

If UFW is managing your rules and you plan to switch to a native nftables ruleset, you'll want to disable UFW to avoid the two systems conflicting:

bash

sudo systemctl disable --now ufw
                            

Step 2: Export Your Existing iptables Ruleset

Save your current rules as a safety net before changing anything:

bash

sudo iptables-save > ~/iptables-backup-$(date +%F).rules
sudo ip6tables-save > ~/ip6tables-backup-$(date +%F).rules
                            

Keep these. If the migration goes sideways, you can restore with iptables-restore and get back to a known-good state in seconds.

Step 3: Translate iptables Rules to nftables Syntax

nftables ships translation utilities that convert legacy syntax to native nft syntax. This won't give you a perfectly idiomatic nftables ruleset, but it's an excellent starting point:

bash

sudo apt install nftables
iptables-restore-translate -f ~/iptables-backup-$(date +%F).rules
                            

Or translate rule-by-rule with iptables-translate:

bash

iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
                            

Step 4: Write a Native nftables Configuration File

Rather than pasting translated one-liners, it's worth writing a clean /etc/nftables.conf from scratch using nftables' table/chain structure. Here's a practical baseline for a server running SSH and a web service:

plaintext

#!/usr/sbin/nft -f

flush ruleset

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

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

        # Allow loopback traffic
        iif "lo" accept

        # Drop invalid packets
        ct state invalid drop

        # Allow ICMP (ping) and essential ICMPv6
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

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

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

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

A few things worth noting here, since they're the most common source of confusion when moving from iptables:

  • table inet covers both IPv4 and IPv6 in one table — this is the single biggest structural change from iptables.
  • tcp dport { 22, 80, 443 } is a native nftables set — one line replaces three separate iptables rules.
  • policy drop on the input chain means you're default-denying, then explicitly allowing what you need.

Step 5: Test Before Making It Persistent

Load the ruleset without committing to it permanently, so a mistake doesn't lock you out:

bash

sudo nft -f /etc/nftables.conf
sudo nft list ruleset
                            

Important: Open a second SSH session while your first one is still connected, and confirm you can still log in. If the second session fails, your first session is still open — you can fix the ruleset before disconnecting.

Step 6: Enable nftables to Persist Across Reboots

Ubuntu and Debian both ship a systemd unit for this:

bash

sudo systemctl enable nftables
sudo systemctl start nftables
                            

By default, this service loads whatever is in /etc/nftables.conf at boot, so any rules you want to survive a reboot need to live in that file.

Rolling Back If Something Goes Wrong

If your new ruleset causes problems, revert immediately back to your iptables setup:

bash

sudo systemctl stop nftables
sudo nft flush ruleset
sudo iptables-restore < ~/iptables-backup-$(date +%F).rules
                            

This is exactly why keeping that Step 2 backup matters — it's your fastest path back to a working state.

iptables vs nftables: Quick Comparison

Aspect iptables (legacy) nftables
IPv4/IPv6 handling Separate tools (iptables, ip6tables) Single inet table for both
Rule grouping Repeated rules per port/IP Native sets and maps
Performance Linear rule evaluation Bytecode-compiled, faster at scale
Tooling iptables, ip6tables, arptables, ebtables Single nft utility
Default on Ubuntu 24.04 / Debian 12 Compatibility layer only (iptables-nft) Native backend

Beyond the OS: Hardware DDoS Protection

While configuring nftables is crucial for OS-level port filtering and securing local services, a software firewall cannot absorb massive volumetric network attacks (like UDP floods or SYN floods) before they saturate your network uplink.

For true enterprise-grade uptime, pair your carefully configured local firewall with our DDoS Protected Dedicated Servers. eServers filters malicious traffic at the data centre edge, ensuring only clean, legitimate traffic ever reaches your server's nftables ruleset.

Frequently Asked Questions

Does Ubuntu 24.04 use iptables or nftables by default?

Ubuntu 24.04 uses nftables as the underlying backend. Commands like iptables are provided through the iptables-nft compatibility layer, so legacy syntax still works, but the kernel-level enforcement is nftables.

Is it safe to run UFW and native nftables rules at the same time?

No. Ubuntu's own documentation advises against running UFW alongside a hand-written nftables ruleset, since both manage the same underlying tables and can produce conflicting or duplicated rules. Pick one.

Do I need to migrate if iptables-nft already works fine?

Not urgently. The compatibility layer will keep working for the foreseeable future. Migrating to native syntax mainly pays off once your ruleset grows large, you need IPv4/IPv6 parity in one place, or you want the performance and set/map features nftables offers.

What happens to my rules after a reboot if I don't enable the systemd service?

They're gone. Rules loaded manually with nft -f are not persistent unless /etc/nftables.conf is loaded automatically via the nftables systemd service on boot.

Discover eServers Dedicated Server Locations

eServers provides reliable dedicated servers across multiple global regions. Whether you need low latency, regional compliance, or proximity to your audience, our wide geographic coverage ensures the perfect hosting environment for your project.

Our Bandwith providers

We are Partners with 15 +

At eServers , we proudly partner with 15+ leading global tech providers to deliver secure, high-performance hosting solutions. These trusted alliances with top hardware, software, and network innovators ensure our clients benefit from modern technology and enterprise-grade reliability.

Hosting Solutions