• Latest
  • Trending
  • All
Linux Firewall Comparison 2026 - ufw vs firewalld vs nftables vs iptables - PeopleAreGeek

Linux Firewall Comparison 2026: ufw vs firewalld vs nftables vs iptables

May 29, 2026
WordPress Security Hardening Checklist: 34 Scored Controls with Copy-Paste Fixes - cover image

WordPress Security Hardening Checklist: 34 Scored Controls with Copy-Paste Fixes

June 3, 2026
Maximizing Website Speed with Image Optimization Techniques for 2026 - cover image

Maximizing Website Speed with Image Optimization Techniques for 2026

June 3, 2026
SSL certificate renewal manager - 8 ACME clients, expiry calculator and monitoring - cover image

SSL Certificate Renewal Manager: certbot, acme.sh, lego, Caddy, cert-manager

June 3, 2026
CORS policy generator - 14 server and framework configs with presets and live security review - cover image

CORS Policy Generator: Headers + Nginx, Apache, Express, FastAPI, Django Config

June 3, 2026
netsh wlan command reference - 72 commands with example output and copy - cover image

netsh wlan Commands: Windows Wi-Fi Cheat Sheet (Show Password, Profiles, Hotspot)

June 2, 2026
Fix: ESXi Host Not Responding / Disconnected in vCenter (2026) - cover image

Fix: ESXi Host Not Responding / Disconnected in vCenter (2026)

June 1, 2026
VMware ESXi Purple Screen of Death (PSOD): Diagnose and Recover (2026) - cover image

VMware ESXi Purple Screen of Death (PSOD): Diagnose and Recover (2026)

June 1, 2026
VMware PowerCLI command generator cover

VMware PowerCLI Command Generator: VM, Snapshots, Networking, esxcli

June 1, 2026
dd Command Generator: Write ISO to USB, Image Disks, Wipe Drives - cover image

dd Command Generator: Write ISO to USB, Image Disks, Wipe Drives

June 1, 2026
SSH Tunnel Command Generator: Local, Remote and Dynamic Forwarding - cover image

SSH Tunnel Command Generator: Local, Remote and Dynamic Forwarding

June 1, 2026
sed Command Generator: Build Substitute, Delete and Print Commands - cover image

sed Command Generator: Build Substitute, Delete and Print Commands

May 31, 2026
VMware Workstation and Hyper-V on the Same Machine (2026 Fix) - cover image

VMware Workstation and Hyper-V on the Same Machine (2026 Fix)

May 31, 2026
  • Online Tools
  • Network Tools
  • Developer Tools
  • Security Tools
Wednesday, June 3, 2026
  • Login
People Are Geek
  • Online Tools
  • Network Tools
  • Developer Tools
  • Security Tools
No Result
View All Result
People Are Geek
No Result
View All Result
Home Server & Admin Tools

Linux Firewall Comparison 2026: ufw vs firewalld vs nftables vs iptables

by People Are Geek
May 29, 2026
in Server & Admin Tools
0
Linux Firewall Comparison 2026 - ufw vs firewalld vs nftables vs iptables - PeopleAreGeek
0
SHARES
2
VIEWS
Share on FacebookShare on Twitter

Deep dive Linux firewalls · 15 min read · Updated May 2026

In 2026 there are four firewall tools you can find in production on Linux: iptables, the legacy interface that everyone still has muscle memory for; nftables, the modern kernel-side replacement that has been default since 2018-2020 depending on the distro; firewalld, the dynamic zone-based daemon used on the RHEL family; and ufw, the human-readable Debian/Ubuntu front-end. All four ultimately program the same kernel — they are user-facing wrappers around the netfilter or nf_tables packet filter. This article compares the four, shows the same rule recipe expressed in each syntax, explains migration patterns, and ends with a decision tree for new installations.

Contents

  1. Why four firewall tools in 2026
  2. The kernel underneath: netfilter vs nf_tables
  3. iptables: the legacy interface
  4. nftables: the modern kernel ABI
  5. firewalld: the dynamic state daemon
  6. ufw: the human-readable front-end
  7. Per-distro defaults
  8. Recipe: same rule in all four syntaxes
  9. Performance and feature comparison
  10. Migration patterns
  11. Decision tree for new installations
  12. Common gotchas
  13. FAQ

Why four firewall tools in 2026

The history is the explanation. iptables shipped with Linux 2.4 in 2001 as the user-facing tool for the netfilter framework. It became the universal default for two decades, accumulated thousands of tutorials, runbooks, Ansible roles and Stack Overflow answers, and entered into the muscle memory of every Linux admin who started before 2018. nftables was developed by the netfilter project itself starting in 2014 as the official successor, addressing iptables’ performance and expressiveness limitations. The Linux kernel quietly switched to the nf_tables backend in 4.x, and distros started shipping nftables as the default around 2018-2020 (Debian 10, RHEL 8, Ubuntu 20.04, openSUSE Tumbleweed). The iptables command still exists on every modern distro but on most of them, it is the iptables-nft shim that translates iptables syntax into nftables rules under the hood. So when you type iptables -L on Rocky 9, you are seeing nftables rules being rendered as iptables would have shown them.

firewalld and ufw are higher-level abstractions that came later for different audiences. firewalld (2011, Red Hat) wraps the kernel layer behind a daemon that exposes zones, services, runtime versus permanent rules, and a D-Bus API. It is the only one of the four with a state daemon. ufw (2008, Ubuntu) does the opposite: it is a thin shell-script wrapper over iptables that turns common operations into one-line commands. Both target users who want a firewall without writing chains.

The kernel underneath: netfilter vs nf_tables

All four tools eventually program a single kernel structure: the packet filter. There are two generations of that structure in the kernel:

  • x_tables (the netfilter framework backing iptables, ip6tables, ebtables and arptables). One module per protocol family, fixed table structure, limited expressiveness for compound rules.
  • nf_tables (the unified replacement). One framework for v4/v6/bridge/arp, programmable VM bytecode in the kernel, atomic rule replacement, much better performance under high rule counts.

Modern distros run the kernel’s nf_tables backend exclusively. iptables, iptables-legacy, iptables-nft, firewall-cmd, ufw, nft are all user-space tools that end up writing nf_tables rules. The exception is when iptables-legacy is explicitly installed alongside the nft backend — that programs the old x_tables structure, which still exists but is deprecated.

iptables: the legacy interface

iptables organises rules into tables (filter, nat, mangle, raw) and chains within each table (INPUT, OUTPUT, FORWARD for the filter table, plus custom chains). Each rule matches packet attributes and decides an action (ACCEPT, DROP, REJECT, jump to another chain).

# List current rules
sudo iptables -L -n -v --line-numbers

# Allow SSH from anywhere
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Set default policy to drop
sudo iptables -P INPUT DROP

# Save rules persistently (Debian/Ubuntu via iptables-persistent package)
sudo netfilter-persistent save

# RHEL 7 style
sudo service iptables save

iptables’ main strengths are familiarity and the immense body of existing documentation. Its weaknesses are: rules cannot be replaced atomically (every -I or -D mutates the live rule set), syntax for any compound condition is verbose, and performance under rule counts above a few thousand degrades non-linearly.

nftables: the modern kernel ABI

nftables replaces the table-and-chain model with a more flexible scheme: you define tables (any name, scoped to a protocol family), chains inside tables (with explicit hook attachment), rules inside chains, and sets and maps as first-class objects for grouping addresses, ports, or interfaces.

# /etc/nftables.conf — full example
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
  set allowed_tcp {
    type inet_service
    elements = { 22, 80, 443 }
  }

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

    iif lo accept
    ct state established,related accept
    tcp dport @allowed_tcp accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
  }
}

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

# List
sudo nft list ruleset

nftables’ advantages over iptables: atomic rule replacement (the entire ruleset swaps in one operation), set and map types that make “allow 17 ports” a single line instead of 17 rules, native IPv4 + IPv6 handling in the same rule, and a kernel implementation that scales to tens of thousands of rules without measurable performance degradation. The downside is the syntax is new — runbooks and tutorials are still catching up.

firewalld: the dynamic state daemon

firewalld introduces three concepts that the other tools do not have: zones (a connection or interface belongs to a zone, the zone has a default policy), services (named bundles of port + protocol — “ssh” rather than “tcp/22”), and runtime versus permanent (changes made without --permanent apply immediately but disappear on reload or reboot).

# Inspect current state
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-all

# Allow SSH, HTTP, HTTPS persistently
sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent

# Custom port range
sudo firewall-cmd --zone=public --add-port=8080-8090/tcp --permanent

# Apply
sudo firewall-cmd --reload

firewalld’s strengths are dynamic operations (the daemon allows changes without flushing the whole ruleset, which iptables does on every save), zone-based logic that suits roaming laptops and multi-interface servers, and a D-Bus API that GUI tools can integrate with. Weaknesses: the abstraction layer hides what is actually being programmed, debugging requires understanding both firewalld zones and the underlying nft ruleset, and the daemon is one more moving part on minimal server installs.

ufw: the human-readable front-end

ufw is the shortest path from “I want SSH and HTTPS open” to “done”:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable

# Verify
sudo ufw status verbose

# Rate-limit (built-in)
sudo ufw limit 22/tcp

ufw is opinionated: it organises rules so most users do not have to think about chains, NAT, or table jumps. The strengths are the smallest learning curve and the fastest “open this port persistently” workflow. The weaknesses are: limited expressiveness (anything beyond simple allow/deny per port falls outside ufw’s vocabulary and you reach for raw iptables or nft), and it does not coexist cleanly with firewalld on the same host (pick one).

Per-distro defaults

Which tool ships pre-installed on each distro covered by our Distro Reference:

DistroDefault firewall front-endKernel backend
Ubuntu 24.04 LTSufw (not enabled by default)nf_tables
Debian 12 BookwormNone pre-installed (nftables.service available)nf_tables
Fedora 40firewalld (enabled)nf_tables
Rocky 9 / Alma 9 / RHEL 9firewalld (enabled)nf_tables
Arch LinuxNone pre-installednf_tables (available via nftables package)
openSUSE Leap 15.5firewalld (enabled, since Leap 15.0)nf_tables
Alpine Linux 3.19None pre-installednf_tables (via nftables package)

Two non-obvious points: Ubuntu ships ufw but does not enable it — a fresh server install has no firewall active until you run ufw enable. Arch and Alpine ship no firewall at all, which catches many first-time admins: a freshly provisioned host has every port open until you install and enable one.

Critical: a freshly installed Arch or Alpine host is exposed on every listening port the moment you boot it. Install and enable a firewall before putting it on a public network.

Recipe: same rule in all four syntaxes

The shared baseline: deny everything inbound except SSH (22), HTTP (80), HTTPS (443) and established connections.

iptables

sudo iptables -P INPUT DROP
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p icmp -j ACCEPT
sudo netfilter-persistent save

nftables

cat | sudo tee /etc/nftables.conf <<'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
  chain input {
    type filter hook input priority 0;
    policy drop;
    iif lo accept
    ct state established,related accept
    tcp dport { 22, 80, 443 } accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
  }
}
EOF
sudo systemctl enable --now nftables
sudo nft -f /etc/nftables.conf

firewalld

sudo firewall-cmd --zone=public --set-target=DROP --permanent
sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload

ufw

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Same result, four very different lines of code. The nft version is the most compact thanks to the { 22, 80, 443 } set syntax. The firewalld version reads almost like English. The ufw version is the fastest to type. The iptables version is the most explicit about what is happening.

Performance and feature comparison

Featureiptablesnftablesfirewalldufw
Atomic rule replacementNoYesYes (via daemon)No (uses iptables under hood)
Sets and mapsNoYesLimited (ipset)No
IPv4 + IPv6 in one ruleNo (two tools)Yes (inet family)Yes (transparent)Yes (parallel rules)
Dynamic API (state daemon)NoNo (rules are static config)Yes (D-Bus)No
Zones / location awarenessNoNoYesNo
Performance at 10k+ rulesSlow (linear)FastDepends on backend (now nft)Inherits from iptables
Learning curveSteep (deep)MediumMedium (concepts)Lowest
Ecosystem (docs, runbooks)HugeGrowingSolid in RHEL worldSolid in Debian/Ubuntu

Migration patterns

iptables → nftables

The official conversion tool is iptables-restore-translate. It reads an iptables-save output and emits the equivalent nftables ruleset. Use it as a starting point, then clean up by hand to take advantage of sets and maps:

sudo iptables-save > /tmp/rules-v4.txt
sudo ip6tables-save > /tmp/rules-v6.txt
iptables-restore-translate -f /tmp/rules-v4.txt > /tmp/rules.nft
ip6tables-restore-translate -f /tmp/rules-v6.txt >> /tmp/rules.nft

# Review the output, edit as needed, then load
sudo nft -f /tmp/rules.nft
sudo systemctl disable --now iptables  # remove the old service
sudo systemctl enable --now nftables

ufw → firewalld (or vice versa)

The two cannot coexist; the migration is “disable one, install the other, recreate the rules”. There is no syntax-level conversion tool because the abstractions are so different (port-level rules vs zone-based rules). Manually re-implement using the cheatsheet in the recipe section above.

Legacy iptables-save format → nftables permanent config on Debian/Ubuntu

If you have an existing /etc/iptables/rules.v4 from iptables-persistent, the cleanest migration on Debian 12 / Ubuntu 24.04 is:

sudo apt install nftables iptables-nftables-compat
sudo iptables-restore-translate -f /etc/iptables/rules.v4 > /etc/nftables.conf
sudo systemctl enable --now nftables
sudo systemctl disable netfilter-persistent

Decision tree for new installations

  • Single Debian / Ubuntu server, a handful of ports, ops team prefers cheatsheets → ufw. Lowest cognitive cost, fastest “open port” workflow.
  • RHEL family server (Rocky, Alma, RHEL, Fedora) → firewalld. It is the default; fighting the default is rarely worth the cost.
  • Container host, K8s node, anything where rules change frequently and atomically → nftables directly. Atomic replacement, performance at scale.
  • Roaming laptop with VPN, captive portals, multiple location profiles → firewalld with zones. It is built for exactly this.
  • Fleet management, runbook-heavy environment, infrastructure as code → nftables (declarative nftables.conf renders cleanly from templates).
  • Legacy environment with hundreds of existing iptables rules → translate via iptables-restore-translate, then maintain as nftables going forward.

See the exact command for your distro?

Our Linux Distro Reference shows the firewall syntax, file paths, workflow and gotcha for each of the 7 supported distros in one click.

Open the reference →

Common gotchas

  • Default policy of DROP without an allow rule on the loopback: locks out the host from itself. Always -A INPUT -i lo -j ACCEPT (iptables) or iif lo accept (nft) before changing the default policy.
  • Forgetting the established/related rule: outbound connections work but replies do not get through. Always allow state established,related on the input chain.
  • ufw and Docker conflict: Docker writes its own iptables/nft rules that bypass ufw. Use the ufw-docker helper or configure Docker with --iptables=false if you need ufw to control container traffic.
  • firewalld silent without –permanent: rules added without --permanent disappear after a reload or reboot, with no warning. Get in the habit of always using --permanent + --reload.
  • Multiple firewall tools on one host: ufw + firewalld + raw iptables fighting. Pick one, disable the others (sudo systemctl mask).
  • IPv6 forgotten: a rule that allows TCP/22 on v4 may leave SSH wide open on v6 if you did not also write the v6 rule. nftables’ inet family solves this; iptables requires both iptables and ip6tables.
  • Persistence not configured: rules applied via iptables -A are gone after reboot unless you save them. Distros each have their own save mechanism (iptables-persistent, nftables.service, firewall-cmd --reload).

FAQ

Should I learn nftables in 2026?

Yes. The kernel has moved on; nftables is what runs underneath everything. You can keep using iptables-nft for legacy rules but knowing native nft syntax pays off when you read modern docs, debug rule loading, or use sets and maps for scale.

Is iptables going away?

The iptables command will be around for years because of the install base. The underlying x_tables backend is technically deprecated but still maintained for compatibility. The realistic prediction: iptables-nft stays usable through 2030, iptables-legacy gets dropped from most distros by 2028.

Can I use ufw on RHEL or firewalld on Ubuntu?

Technically yes. ufw is in EPEL for RHEL; firewalld is in Ubuntu’s universe repository. Neither is the path of least resistance. The cost is using a tool the rest of the ecosystem (documentation, package interactions, your colleagues’ muscle memory) does not expect.

What about pf?

pf is BSD-only (OpenBSD, FreeBSD, macOS). It does not exist on Linux. If you are coming from BSD and reflexively typing pfctl, the closest mental model on Linux is nftables — declarative, table-and-chain, atomic replacement.

Do I still need fail2ban with a proper firewall?

Yes. The firewall blocks based on port and source IP — it does not look at the content of established connections. fail2ban (or its successors) watch the application logs and inject temporary block rules when a pattern of failures matches. They complement, not replace.

Can I run a stateless firewall for performance?

nftables supports stateless rules (skip the ct state match) and can run at line rate on modern NICs for simple drop/allow logic. But stateless rules cannot detect reply traffic — every direction needs an explicit rule. Useful for edge routers, overkill for application servers.

Related on PeopleAreGeek

Linux Distro Reference (per-distro firewall syntax) Linux Hub (series overview) Network config across Linux distros Ubuntu 24.04 hardening checklist TLS Version Selector Cyber Audit Suite All tools and articles
ShareTweetPin
People Are Geek

People Are Geek

I'm Stephane, a network and systems engineer with over 15 years of hands-on experience on production infrastructure, virtualization (ESXi, Proxmox), networking, and self-hosting. Earlier in my career I built and ran a Linux resource site that became a well-known reference for sysadmins. Today I focus on cybersecurity, and I also work as a technical trainer, teaching networking and security to people who do it for a living. Everything on People Are Geek comes from real-world practice, not theory. I build every tool on this site myself, and I write about what I've actually deployed, broken, and fixed. If it's here, I've used it.

People Are Geek

Copyright © 2017 JNews.

Navigate Site

  • About PeopleAreGeek
  • All Tools and Articles
  • Contact
  • Cookie Policy
  • Hyper-V Hub: Tools, Error Fixes and Lab Guides
  • Linux Hub: Cross-Distro Reference, Articles, Tools
  • Page de test Codex
  • Privacy Policy
  • Sample Page
  • Terms of Service
  • VMware vSphere & ESXi Hub: Tools, Error Fixes and Guides

Follow Us

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Online Tools
  • Network Tools
  • Developer Tools
  • Security Tools

Copyright © 2017 JNews.