Security

UFW vs firewalld vs nftables vs iptables: which Linux firewall to use

UFW, firewalld, nftables and iptables are not four rival firewalls. Learn how they fit together, what each distro uses by default and how to pick one tool for your VPS.

BeginnerLinux server5 min read

Linux has one packet filter in the kernel, called netfilter, and several tools for writing rules into it. UFW, firewalld, nftables and iptables are those tools. This guide explains how they relate, which one your distribution expects, and how to choose one and stick with it so your rules stay predictable.

Before you start

  • A Linux VPS with root or sudo access over SSH.
  • Know which distribution you run. Check with:
Bash
  cat /etc/os-release
  • Know how to reach the browser console in the control panel of your VPS provider's control panel. It works even if a firewall rule blocks SSH.

How the four tools fit together

Think of it as layers, from the kernel up:

  • netfilter is the filtering engine inside the Linux kernel. Every tool below writes rules for it.
  • iptables is the classic command-line tool. It has separate commands for IPv4 (iptables) and IPv6 (ip6tables).
  • nftables (the nft command) is the modern replacement for iptables. One ruleset covers IPv4 and IPv6, and it supports sets and maps natively.
  • UFW (Uncomplicated Firewall) is a friendly front end. You type ufw allow 22/tcp and it writes the low-level rules for you.
  • firewalld is another front end, built around zones and services. It uses nftables as its backend on current releases.

On modern distributions the iptables command itself is usually iptables-nft: it accepts the old syntax but stores the rules in nftables. Check yours:

Bash
iptables --version

Output ending in (nf_tables) means the nftables backend. (legacy) means the old kernel tables.

What each distribution uses by default

  • Ubuntu 22.04 and 24.04: UFW is installed but inactive. It is the natural choice on Ubuntu.
  • Debian 12: nftables is the default framework. UFW is not installed by default but is available with apt install ufw.
  • AlmaLinux and Rocky Linux 8 and 9: firewalld is installed and normally enabled, using nftables underneath.

Your provider image may differ slightly, so check what is actually active:

Bash
systemctl is-active ufw firewalld nftables
sudo ufw status 2>/dev/null
sudo firewall-cmd --state 2>/dev/null

When to pick each tool

  • Pick UFW on Ubuntu or Debian when you want a few simple allow rules: SSH, HTTP, HTTPS. It is the easiest to read and hard to get badly wrong. Start with Set up UFW on Ubuntu and Debian.
  • Pick firewalld on AlmaLinux or Rocky Linux, or when you want zones, such as a trusted zone for your office IP. Start with Set up firewalld on AlmaLinux and Rocky Linux.
  • Pick nftables directly when you need full control: complex NAT, large sets of IPs, or a single readable config file under version control. The nftables basics guide covers the syntax.
  • Pick iptables only when an older script or tool requires it. For new setups, nftables does the same job with cleaner syntax.

Control panels and some apps bring their own firewall. cPanel and DirectAdmin often use CSF, and Plesk has its own firewall extension. If you use a panel, manage the firewall through the panel instead of adding another tool.

Never run two firewall managers

Each front end assumes it owns the ruleset. If UFW and firewalld both run, they overwrite or shadow each other's rules, and a reboot can leave you with a ruleset neither tool expects. Pick one and disable the others.

Warning: Before you enable any firewall, allow SSH first. A default-deny policy without an SSH rule cuts your session and blocks new logins. If that happens, log in through the browser console in your VPS provider's control panel and fix the rule.

For example, to keep UFW and remove firewalld on a Debian-family server:

Bash
sudo ufw allow OpenSSH
sudo systemctl disable --now firewalld
sudo ufw enable

Or to keep firewalld and drop UFW on an AlmaLinux server:

Bash
sudo systemctl disable --now ufw
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

If you moved SSH to a custom port, allow that port instead of the service name.

Docker is a special case. It inserts its own iptables or nftables rules for published ports, which can bypass UFW. If you run containers, read the guide on stopping Docker from bypassing UFW.

Check it works

Confirm only one manager is active:

Bash
systemctl is-active ufw firewalld nftables

Then view the effective ruleset that the kernel is using, whatever tool wrote it:

Bash
sudo nft list ruleset | less

Finally, open a second SSH session from your computer before closing the first. If it connects, your SSH rule works.

Troubleshooting

  • Rules you added disappear after a reboot: two tools are fighting, or you used a raw iptables command without saving it. Disable the extra manager and save rules the way your chosen tool expects.
  • ufw status shows a port open but it is still blocked: another layer, such as firewalld or a leftover nftables table, is dropping it. Check sudo nft list ruleset for tables UFW did not create.
  • iptables -L is empty but traffic is filtered: your rules live in nftables. Use nft list ruleset instead.
  • Locked out after enabling a firewall: use the browser console in your VPS provider's control panel, disable the firewall, add the SSH rule and enable it again. See Locked out by your firewall?.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.