SERVER SECURITY GUIDE

Linux Firewall Guide: iptables vs nftables vs ufw

iptables, nftables, and ufw are three layers of the same Linux firewall stack, not three competing products. nftables is the modern kernel packet-filtering framework that has replaced iptables as the default on every major distribution since 2022, iptables now runs as a compatibility layer on top of it, and ufw is a simplified command-line frontend that can drive either backend. For most small business VPS setups, ufw configured with a default-deny policy is the fastest safe choice, with direct nftables rules reserved for more complex needs.

Quick win (10 minutes)

  • Run sudo ufw status verbose or sudo nft list ruleset to see what is actually enforced on your server right now.
  • Confirm SSH access is allowed on your current port before you enable or change any default-deny policy, or you can lock yourself out.
  • Set default incoming traffic to deny and default outgoing traffic to allow as your starting baseline.
  • Explicitly allow only the ports your services actually need (SSH, and HTTP/HTTPS if you run a web server).
  • Enable logging for denied packets so you have a record to check later.

This guide is the firewall-specific companion to our VPS security checklist, which covers the full baseline a small business server needs beyond just the firewall layer.

What do iptables, nftables, and ufw actually do?

All three tools control which network packets are allowed to reach or leave your server, but they operate at different levels: nftables is the kernel-level packet filtering engine, iptables is either the older engine or a translation layer on top of nftables, and ufw is a human-friendly command layer on top of either one. Understanding this layering is the key to not being confused by seemingly conflicting rule outputs.

A host firewall is your server's first line of defense against unwanted network traffic, sitting below your application and independent of it. Every open port is a potential entry point, so the firewall's job is to make sure only the ports you have deliberately decided to expose (typically SSH and, if applicable, HTTP/HTTPS) can be reached from outside, while everything else is dropped before it ever touches your applications.

iptables: the original Linux firewall

iptables is the classic Linux packet filter, built around fixed tables (filter, nat, mangle, raw) and chains (INPUT, OUTPUT, FORWARD) that packets are checked against in order. It has been the standard Linux firewall tool for over two decades and its syntax is still widely documented and understood.

According to the nftables project's own comparison documentation, iptables relies on a getopt_long()-based command parser with predefined tables and chains, and every added or removed rule effectively reloads the whole ruleset as a monolithic block. iptables also does not support combined IPv4/IPv6 (dual stack) rulesets natively, so administrators traditionally had to maintain a parallel ip6tables ruleset for IPv6 traffic. On current Ubuntu, Debian, and RHEL-family systems, the iptables command you type is typically translated into nftables rules behind the scenes rather than talking to the old kernel modules directly, which is why you may see your iptables rules appear when you run nft list ruleset.

nftables: the modern replacement

nftables is the current default packet filtering framework on every major Linux distribution, replacing iptables with a more flexible and efficient design. According to the nftables wiki, nftables has no predefined tables or chains at all: you explicitly define only the structures you need, which reduces unnecessary rule evaluation compared to iptables' fixed set.

Three technical differences matter most in practice. First, a single nftables rule can combine multiple match expressions and multiple actions (statements) in one line, where iptables often needs several separate rules to do the same thing. Second, nftables' inet family lets you write one rule set that applies to both IPv4 and IPv6 traffic simultaneously, removing the need to duplicate rules for ip6tables. Third, nftables stores its ruleset internally as a linked list rather than a monolithic blob, so individual rules can be added or removed atomically without reloading and briefly exposing the server during the reload window.

The tradeoff is a steeper learning curve. nftables syntax is closer to a small domain-specific language, and administrators moving from iptables muscle memory need to relearn table and chain declarations before writing their first rule.

ufw: the simple frontend

ufw (Uncomplicated Firewall) is a simplified command-line tool, originally built for Ubuntu, that generates iptables or nftables rules for you from short, readable commands like ufw allow 22/tcp. It does not replace the underlying engine, it drives it.

ufw is stateful by design, meaning it automatically tracks the state of active connections so that reply traffic for a connection you initiated is allowed back in without a separate rule. On Ubuntu, the nftables backend for ufw has been the default since Ubuntu 20.10, so on a current Ubuntu VPS your ufw commands are quietly generating nftables rules, while on older systems or other distributions ufw may still generate legacy iptables rules. You can confirm which backend is active with update-alternatives --display iptables.

Which one should you use?

For a single small business VPS running SSH and a web stack, ufw is usually the right default because it minimizes the chance of a misconfiguration locking you out or leaving a port open by accident. Reach for nftables directly only when you need custom chains, rate limiting, connection tracking beyond ufw's exposed options, or NAT rules that ufw's syntax does not cover.

Factoriptablesnftablesufw
Status in 2026Maintenance mode; runs via nftables compatibility layer on most modern distrosDefault engine on Ubuntu 22.04+, Debian 11+, RHEL 9+Frontend, not an engine; drives iptables or nftables
Learning curveFamiliar to long-time Linux adminsSteeper, new syntaxLowest; short readable commands
IPv4/IPv6 in one rulesetNo, needs ip6tables in parallelYes, via the inet familyHandled automatically by ufw
Best fitLegacy scripts, existing rulesetsComplex custom rules, NAT, rate limitingSmall VPS, quick safe baseline

Want a second opinion on your current firewall rules?

Get a free, read-only server security check, or talk to a security engineer about managed protection.

Get your free server check Talk to a security engineer

How to set up a basic nftables firewall

A minimal safe nftables setup creates one input chain with a default drop policy, then explicitly allows loopback traffic, established connections, SSH, and any web ports you run. Below is a starting ruleset you adapt to your own ports.

sudo nft flush ruleset

sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }

sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
sudo nft add rule inet filter input ct state invalid drop

sudo nft list ruleset

Test this over a second connection or console access before you rely on it, since a typo in the SSH rule can cut off your only way in. Once verified, persist the ruleset (commonly saved to /etc/nftables.conf and loaded on boot via systemd) so it survives a reboot.

How to set up ufw in 10 minutes

A safe ufw baseline sets default deny for incoming traffic, default allow for outgoing traffic, explicitly allows SSH before enabling the firewall, and then enables it. CIS benchmark guidance for Debian-family systems specifically calls out setting a default deny incoming policy as a scored, security-relevant control.

sudo apt install 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
sudo ufw status verbose

Always allow your SSH port before running ufw enable. If you have changed SSH off the default port 22 as part of your SSH hardening work, allow that specific port instead, not 22. If you manage the server through a cloud provider's own network-level firewall or security group in addition to ufw, remember both layers must allow the traffic, a block at either layer stops the connection.

Common firewall mistakes that leave servers exposed

The most common firewall failure on small business servers is not a missing firewall, it is a firewall installed but never set to default-deny, leaving every port that any installed package happens to open silently reachable. The second most common failure is enabling default-deny without first confirming SSH is allowed, which causes a lockout that requires console or provider-panel access to fix.

Firewall configuration is one item on a longer list. For the full baseline covering SSH, updates, monitoring, and backups together, see the complete VPS security checklist, and for foundational steps before you even touch firewall rules, see our SSH hardening guide.

Two caveats to know before you rely on host firewall rules: published Docker ports can bypass them, as explained in the Docker host security guide, and a firewall is only one layer for keeping databases private, covered in exposed databases on a VPS.

Frequently asked questions

Is nftables faster than iptables?

nftables can be more efficient on large or complex rulesets because it uses a single unified kernel interface, a linked-list ruleset that updates rules without reloading everything, and lets one rule run multiple statements instead of requiring separate iptables rules for each match. On a small server with a short ruleset the practical difference is usually negligible.

Should I use ufw or nftables directly on a VPS?

Use ufw if you want a small number of allow and deny rules managed quickly and safely. Use nftables directly if you need custom chains, rate limiting, NAT, or fine-grained control that ufw's simplified syntax does not expose.

Is iptables deprecated?

The classic iptables tool is in maintenance mode, and every major Linux distribution, including Ubuntu 22.04 and later, Debian 11 and later, and RHEL 9 and later, now ships nftables as the default packet filtering framework. The iptables command still works on these systems through a compatibility layer that translates it into nftables rules.

ufw or iptables: which is better?

For most small VPS setups, ufw is the better choice: it is a frontend, not a separate engine, and it manages iptables or nftables underneath while keeping commands short and hard to get wrong. iptables itself is now in maintenance mode. Reach for nftables directly, or ufw's underlying nftables backend, only when you need custom chains, rate limiting, or NAT that ufw's simplified syntax does not expose.

Does ufw use iptables or nftables?

It depends on the distribution and version. On Ubuntu, the nftables backend for ufw has been the default since Ubuntu 20.10, so ufw commands are translated into nftables rules under the hood while still exposing the same simple ufw allow and ufw deny commands.

What is a default deny firewall policy and why does it matter?

A default deny policy blocks every connection that is not explicitly allowed, instead of allowing everything except what is explicitly blocked. Security benchmarks recommend default deny because it is far easier to maintain a short allow list than to anticipate every possible unwanted connection.

Can a firewall alone protect a VPS from a breach?

No. A firewall reduces exposed attack surface by closing unused ports, but it does not stop credential stuffing against an open SSH port, application vulnerabilities, or malware delivered through an allowed service. It needs to be paired with SSH hardening, monitoring, and patching.

Do I need both a firewall and fail2ban?

Yes, they solve different problems. A firewall controls which ports and IP ranges can reach a service at all, while fail2ban watches logs and temporarily bans IPs that generate repeated authentication failures on a port you have intentionally left open, such as SSH.

How do I check my current firewall rules on Linux?

Run sudo nft list ruleset for nftables, sudo iptables -L -n -v for the legacy iptables interface, or sudo ufw status verbose if ufw is installed. It is worth checking all three, since a server can have ufw rules sitting on top of an nftables or iptables backend.

Not sure where your server stands?

Get a free, read-only security check, or talk to a security engineer about managed protection.

Get your free server check Talk to a security engineer