Skip to main content
RunBook Academy

LinuxXXV · Firewallsiptables

iptables legacy and migration to nftables

Intermediate⏱ ~10 miniptablesnft

What you'll learn

  • Read an iptables ruleset
  • Understand why iptables is deprecated
  • Migrate an iptables ruleset to nftables
  • Use iptables-nft as a compatibility layer

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

iptables is the legacy Linux firewall tool. It is deprecated in favour of nftables but still appears in older documentation and existing rulesets. This lesson covers iptables, the migration path, and the iptables-nft compatibility layer.

Why iptables is deprecated

The Linux kernel team has merged nftables as the unified firewall API. iptables now runs as a compatibility shim over nftables. Issues with iptables:

  • Separate binaries for IPv4 (iptables), IPv6 (ip6tables), ARP (arptables), bridge (ebtables).
  • Verbose syntax with separate commands for every option.
  • No native transactional updates - rules apply one at a time.
  • Limited counters and no native sets.

nftables fixes all of these with a unified syntax, atomic updates, and better performance.

The iptables tables and chains

sudo iptables -L -n -v              # list filter table
sudo iptables -t nat -L -n -v       # list NAT table
sudo iptables -t mangle -L -n -v    # list mangle table
sudo iptables -t raw -L -n -v       # list raw table

Tables: filter (default), nat, mangle, raw, security. Chains: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING. Each chain has a default policy (ACCEPT or DROP).

A minimal iptables ruleset

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow established
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow SSH from management
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT

# Allow ICMP from monitoring
iptables -A INPUT -p icmp -s 10.0.0.0/24 -j ACCEPT

# Drop invalid
iptables -A INPUT -m state --state INVALID -j DROP

The -m flag loads a module (state, conntrack, multiport, etc.). The -j flag is the jump target (ACCEPT, DROP, REJECT, LOG, or a user-defined chain).

Migration to nftables

Step 1: install nftables and iptables-nft (often already installed).

Step 2: dump the iptables ruleset in a format nft can understand:

iptables-save > /tmp/iptables.rules

Step 3: translate the saved ruleset with iptables-restore-translate:

# Note the tool name: iptables-RESTORE-translate takes a file.
iptables-restore-translate -f /tmp/iptables.rules > /tmp/translated.nft

# Make the file idempotent, then check and load it.
sed -i '1i flush ruleset' /tmp/translated.nft
nft -c -f /tmp/translated.nft     # check syntax, change nothing
nft -f /tmp/translated.nft        # apply atomically

Step 4: validate the new ruleset behaves the same way. Translation is mechanical; equivalence is not. Compare the rulesets you actually intend to compare, and then test behaviour from outside the host:

# Before the change, on the still-legacy host:
nft list ruleset > /tmp/ruleset.before
sudo nmap -Pn -p- firewall-host > /tmp/scan.before   # from a peer host

# After loading /tmp/translated.nft:
nft list ruleset > /tmp/ruleset.after
diff -u /tmp/ruleset.before /tmp/ruleset.after

sudo nmap -Pn -p- firewall-host > /tmp/scan.after
diff -u /tmp/scan.before /tmp/scan.after             # must be empty

The external scan is the part that matters. It is the only check that tests the reachability your users depend on rather than the text of a config file.

iptables-nft compatibility layer

Most modern distributions ship iptables-nft, which routes iptables commands through the nftables backend:

ls -l /usr/sbin/iptables
update-alternatives --display iptables

On RHEL, the alternatives are iptables-legacy and iptables-nft. On Debian, similar.

If you have a service that hard-codes iptables commands and you want to use nftables underneath:

sudo update-alternatives --set iptables /usr/sbin/iptables-nft

iptables commands now create nftables rules transparently.

Read iptables output

iptables -L -n -v --line-numbers

Output:

num   pkts bytes target   prot opt in  out  source         destination
1    1234  100K ACCEPT   all  --  lo  any  0.0.0.0/0      0.0.0.0/0
2     987  65.2K ACCEPT   all  --  any any  0.0.0.0/0      0.0.0.0/0     state RELATED,ESTABLISHED
3       0      0 ACCEPT   tcp  --  any any  10.0.0.0/24   0.0.0.0/0      tcp dpt:22
4      42   3.5K ACCEPT   icmp --  any any  10.0.0.0/24   0.0.0.0/0

The line numbers are essential for inserting or deleting specific rules.

Persist iptables rules

# Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save

# RHEL family
sudo yum install iptables-services
sudo service iptables save

This saves the current rules to /etc/iptables/rules.v4 (Debian) or /etc/sysconfig/iptables (RHEL).

Knowledge check

Knowledge check · 5 questions

  1. Q1. Why is iptables deprecated in favour of nftables?

  2. Q2. iptables-nft routes iptables commands through the nftables backend.

  3. Q3. Which of the following are iptables tables? Select all that apply.

  4. Q4. You have /tmp/iptables.rules from iptables-save and want the whole ruleset in nft syntax. Which command do you run?

  5. Q5. Once nft -c -f accepts the translated file, the migration is verified.

Passing score: 75%. Answers are checked in this browser.