30 September 2025
Linux Firewalls
During the course of its history, Linux has had several built-in firewall stacks. ipfirewall was superseded early in the 2.x kernel series by ipchains, which was replaced by iptables in 2.4. The project (netfilter) responsible for iptables replaced it in 2014 with nftables and made iptables a front end for nftables.
On a modern Linux system, the command iptables -V
will produce output like: iptables v1.8.11 (nf_tables)
. The nf_tables in parentheses indicates that iptables wraps nf_tables. The nft utility can be used to manage firewall rules. For modern releases of iptables, ufw, and firewalld, the rules created can be seen with the nft list ruleset
command. However, the command doesn’t show which interface created the rule! Rules created directly with nft are invisible to the other front ends.
Comparison of Front Ends
Feature | iptables | nft | ufw | firewalld |
---|---|---|---|---|
Persisting Changes | requires iptables-save command and iptables service to load rules from saved file | similar to iptables; rules in /etc/nftables.conf or /etc/nftables/*.nft will be loaded by the service | changes made interactively are permanent; the config is stored in /etc/ufw/user.rules | interactive changes are ephemeral but can be made permanent with the --permanent flag or firewall-cmd --runtime-to-permanent |
Complexity | rule syntax is terse and cryptic | rule syntax is comparable to iptables but less terse, parts of syntax inspired by tcpdump | simplest rule syntax | core syntax for basic rules is comparable to ufw, with the addition of having to specify zone; complex rules can be created with the rich-rules feature |
Interface/Zone Binding | tables can be defined and rules bound to adapters | tables and chains are similar to iptables | rules can be applied per adapter | zone concept similar to Windows Firewall, cumbersome since all commands need to specify zone; rarely a useful feature on servers |
Capability | can implement sophisticated and complex rulesets | goes beyond firewall rules; more advanced features like bridge interfaces are built in nft on modern distros | handles most common rules | has ability to create more complex rules with rich rules, less powerful than iptables and nft |
Avoiding Conflict
The easiest way to avoid conflict is to use only one front end. When you enable one, you should ensure the others are disabled. However, you can’t disable nftables or prevent packages from creating rules. nft list ruleset
is a command you need to know, even if you don’t write rules in it. For example, Docker creates a lot of networking rules, and setting up a bridge interface for Kernel Virtualization creates nft rules to implement it. The only place you can see all running rules is through nft.
Writing Rules
Since all rules are really translated to nft and the only place they are completely visible is through nft, nft is the best place to manage firewall rules. There are practical barriers to just switching to it. iptables has been around for a long time, organizations with more complex rules already have iptables in place, and nft is another complex system to master. In environments where ufw and firewalld are sufficient, they remain good choices.
Here are a few commands that are useful to know:
nft list ruleset # View all active nftables rules
nft flush ruleset # Remove all nftables rules (use with caution!)
nft delete rule inet filter input handle 17 # handle number from nft list ruleset
Here is a comparison of a basic rule to allow SSH. The nft version of the rule is a little friendlier than the iptables version. The ufw version of the command is much cleaner than the firewalld version.
# both iptables and nft require permanent rules in a file, and may also
# require setting up chains and tables in the configuration.
# the example presumes the inet table and chains already exist for both iptables and nft.
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
nft add rule inet filter input tcp dport 22 accept
ufw allow ssh
firewall-cmd --zone=public --add-service=ssh --permanent
# alternately you may use the port instead of the predefined service
# in both ufw and firewalld
ufw allow 22/tcp
firewall-cmd --zone=public --add-port=22/tcp --permanent
Here’s an example of allowing SSH only from a single host.
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT
nft add rule inet filter input ip saddr 192.168.1.100 tcp dport 22 accept
ufw allow from 192.168.1.100 to any port 22 proto tcp
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'
firewall-cmd --reload # must reload to activate new rich rule.
Why I Strongly Prefer ufw to firewalld
The examples above demonstrate that ufw is a much easier basic firewall front end. Beyond syntax simplicity, firewalld has several practical drawbacks:
-
Zone complexity: Every command requires specifying a zone, adding unnecessary complexity for most server use cases where a single security policy applies.
-
Two-step process: Changes require either the
--permanent
flag or a separate--runtime-to-permanent
command, creating opportunities for mistakes. -
Rich rule syntax: Complex rules require XML-like rich rule syntax that’s prone to escaping issues. From the examples we can see that you often have to go to rich rules for things that ufw can handle with simpler syntax.
-
Historical baggage: During the RHEL 7 lifecycle, firewalld used an outdated interface to iptables, which exacerbated compatibility issues as nftables phased in.
In contrast, ufw provides immediate permanent changes, intuitive syntax, and handles the most common firewall scenarios without the overhead of zones or complex rule formats. For the 90% of use cases involving basic allow/deny rules, ufw is simply the better choice.
Conclusion
For basic firewalls, ufw is easier to write rules for, while rich rules allow firewalld the ability to handle some more complex rules. nft and iptables are more powerful and don’t get into the escaping issues of the rich rule.
My choice for basic firewall management is ufw, with an awareness of nft. For advanced rulesets, nft is the clear choice. The netfilter project considers iptables legacy, and even includes a utility iptables-translate in the distribution. For organizations with existing iptables rules, AI coding assistants can be a big help in translating them for a transition.
Helpful Links
If you’re interested in transitioning to nftables, here are some resources for getting started.