Securing a Linux server starts at the network perimeter. In the Linux ecosystem, packet filtering and network address translation (NAT) happen inside the kernel via frameworks like Netfilter and nftables.
However, administrators rarely interact directly with the kernel interface. Instead, user-space management tools are used to control traffic. The two most established utilities are iptables and firewalld.
Understanding how each operates—and where they differ—is essential for server hardening and infrastructure management.
1. The Underlying Engine: Netfilter vs. nftables
Before comparing the tools, it is crucial to understand what is happening under the hood:
Netfilter: The legacy Linux kernel subsystem that inspects, manipulates, and filters network packets.
nftables: The modern successor to Netfilter, designed to provide better performance, unified IPv4/IPv6 syntax, and atomic rule updates.
Both iptables and firewalld act as front-ends to these kernel subsystems.
2. What is iptables?
iptables is the traditional, static packet-filtering utility found across almost every classic Linux distribution.
Core Concepts
iptables organizes rules into a hierarchy of Tables, Chains, and Targets:
Tables: Categories based on packet handling type:
filter(default): General packet filtering.nat: Network address translation (e.g., port forwarding, masquerading).mangle: Specialized packet alteration (modifying headers/TOS).raw: Configuring exemptions from connection tracking.
Chains: The points in network traversal where rules trigger:
INPUT: Packets destined for the local system.OUTPUT: Packets generated by the local system.FORWARD: Packets routed through the local system (routers/gateways).PREROUTING/POSTROUTING: Used in NAT/mangle before or after routing decisions.
Targets: The action taken if a rule matches (
ACCEPT,DROP,REJECT,LOG).
Common iptables Commands
# List all active rules with line numbers and packet counters
sudo iptables -L -v -n --line-numbers
# Allow incoming SSH traffic (port 22)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow incoming HTTP and HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow established and related incoming connections
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Drop all other incoming traffic (Set default policy)
sudo iptables -P INPUT DROP
# Delete a specific rule by chain and line number
sudo iptables -D INPUT 2
Key Characteristic:
iptablesrules are stateless and immediate in-memory. If you restart the server without saving rules (using tools likeiptables-persistent), all runtime rules are lost. Additionally, modifying a rule often requires reloading the complete chain.
3. What is firewalld?
firewalld is a dynamic firewall daemon developed primarily by Red Hat and widely used in RHEL, Rocky Linux, AlmaLinux, Fedora, and openSUSE.
Instead of static chains, firewalld manages security dynamically using Zones and Services over D-Bus.
Core Concepts
Dynamic Management: Rules can be added, updated, or removed on the fly without breaking active connections or restarting the firewall daemon.
Zones: Pre-defined sets of trust levels assigned to specific network interfaces or source IPs.
drop: All incoming connections are dropped without a reply.block: Incoming connections are rejected with an ICMP response.public: For untrusted public networks; allows only explicitly selected incoming connections.internal/home/work: Higher trust levels with broader default access.trusted: All incoming traffic is accepted.
Services: Abstractions for application ports and protocols (e.g., the
httpservice automatically maps to port80/tcp).
Common firewalld Commands
# Check firewall daemon status
sudo firewall-cmd --state
# Get the default active zone
sudo firewall-cmd --get-default-zone
# List all open ports and services in the active zone
sudo firewall-cmd --list-all
# Allow HTTP and HTTPS permanently
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Allow a specific custom port (e.g., 8080 TCP)
sudo firewall-cmd --permanent --add-port=8080/tcp
# Reload configuration to apply permanent changes without connection drops
sudo firewall-cmd --reload
# Remove a service
sudo firewall-cmd --permanent --remove-service=http
Key Characteristic: Changes made with
--permanentwrite to XML configuration files in/etc/firewalld/zones/and persist across reboots once reloaded.
4. Head-to-Head Comparison
| Feature | iptables | firewalld |
| Model | Static, procedural rule lists | Dynamic, zone-based management |
| Runtime Updates | Flushes and rewrites full chains (can disrupt sessions) | Dynamic updates via D-Bus (zero downtime) |
| Persistence | Volatile in-memory (requires third-party save tools) | Native persistent storage via XML configs (--permanent) |
| IPv4 / IPv6 | Handled by separate binaries (iptables vs ip6tables) | Unified management for both IPv4 and IPv6 |
| Default Ecosystem | Legacy Debian/Ubuntu, Docker, embedded systems | RHEL, Rocky Linux, CentOS Stream, Fedora |
| Learning Curve | Steep syntax; requires deep understanding of packet flow | High-level abstraction; simple service and zone mapping |
5. Which One Should You Use?
Use
firewalldif:You run RHEL-derived distributions (RHEL, AlmaLinux, Rocky Linux, Fedora).
You manage servers with multiple network interfaces and differing trust levels.
You need to update firewall rules dynamically without interrupting existing active connections.
Use
iptables(or directnftables) if:You need fine-grained, raw packet manipulation or custom packet routing logic.
You are writing low-level shell scripts for network gateways or custom router appliances.
You are debugging container network forwarding policies (such as Docker bridge networking).
Conclusion
Both iptables and firewalld serve the same fundamental purpose: regulating network packets to protect your system. While iptables provides raw, granular control at the chain level, firewalld delivers a scalable, zone-based management framework ideal for dynamic enterprise environments.




