🔐 Looking to level up your Linux firewall game?
In my latest blog post, I dive into Firewalld — the dynamic, zone-based firewall manager that’s built for modern Linux systems. If you’ve worked with iptables
or ufw
, this is the next step in gaining fine-grained, real-time control over your server’s network traffic.
Introduction
In our previous blog posts, we explored two foundational tools for Linux firewall management: iptables
and ufw
. While powerful in their own right, both have limitations when it comes to managing complex network environments or making real-time changes. That’s where Firewalld steps in.
Firewalld provides a more modern, dynamic, and zone-based approach to managing firewall rules. It’s particularly useful for systems that require frequent rule changes without restarting the firewall service—such as servers handling multiple interfaces or dynamic network scenarios.
In this article, we’ll dive into the core concepts of Firewalld and share best practices that can help you maintain a secure and efficient firewall configuration.
Concept of Firewalld
Zones and Their Purpose
At the heart of Firewalld is the concept of zones. Unlike iptables
, which focuses on rules, or ufw
, which relies on profiles, Firewalld introduces zones as logical groupings that define trust levels for network interfaces.
Each zone has its own set of rules and behaviors:
trusted
: All incoming connections are allowed.home
,internal
: Designed for trusted networks like home LANs.public
: Suitable for untrusted networks like the internet.dmz
,work
: For specific network topologies.drop
,block
: Strict zones that reject or silently drop connections.
By assigning network interfaces to specific zones, you can apply different rule sets per interface. This makes managing complex networks much more intuitive.
Runtime vs Permanent Configuration
Firewalld supports two types of configuration states:
- Runtime: Changes applied immediately but lost on reboot.
- Permanent: Changes saved to disk and persistent across reboots.
This dual-state system allows for testing configurations live without risking permanent changes. Once a rule works as expected, it can be made permanent by either reapplying it with the --permanent
flag or running:
firewall-cmd --runtime-to-permanent
Services vs Ports
Firewalld simplifies rule management by allowing administrators to define or use services rather than manually managing individual ports. For example:
firewall-cmd --zone=public --add-service=http
is more intuitive and maintainable than:
firewall-cmd --zone=public --add-port=80/tcp
Custom services can also be defined in XML and reused across different zones, enhancing consistency and modularity in rule definitions.
Interfaces and Zones
Every network interface can be assigned to a zone:
firewall-cmd --zone=internal --change-interface=eth1
Only one zone can be associated with an interface at a time. The zone controls which services or ports are allowed on that interface. This provides granular control over how your system interacts with different parts of a network.
Rich Rules
For scenarios that require advanced matching criteria (e.g., IP-based filtering, logging, or forward control), Firewalld offers rich rules.
Example:
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="192.168.1.10" service name="ssh" accept'
Rich rules allow you to incorporate features like logging, rate limiting, and more detailed matching conditions, which go beyond basic port/service definitions.
Backend Integration
Though Firewalld is a frontend management tool, it still relies on well-established packet filtering backends such as:
nftables
(modern default)iptables
(legacy support)
Firewalld abstracts away the complexity of backend rule chains, making firewall management easier and less error-prone.
Hands-On: Installation, Network Diagram & Configuration
Installation
For Debian/Ubuntu Systems
# Install firewalld
sudo apt update
sudo apt install firewalld
# Enable and start the service
sudo systemctl enable firewalld
sudo systemctl start firewalld
# Check service status
sudo systemctl status firewalld
For RHEL-based Systems (CentOS, Fedora, RHEL)
# Install firewalld
sudo dnf install firewalld
# Enable and start the service
sudo systemctl enable firewalld
sudo systemctl start firewalld
# Check service status
sudo systemctl status firewalld
Network Zone Diagram
Below is a text-based diagram showing a common firewalld setup with three zones:
+-------------------+
| INTERNET |
+--------+----------+
|
|
|
+--------------v--------------+
| Linux Server |
| |
| +---------------------+ |
| | external zone | |
| | (eth0) | |
| +----------+----------+ |
| | |
| v |
| +----------+----------+ |
| | dmz zone | |
| | (eth1) | |
| +----------+----------+ |
| | |
| v |
| +----------+----------+ |
| | internal zone | |
| | (eth2) | |
| +----------+----------+ |
+-------------|---------------+
|
|
v
+-------------+-------------+
| Internal LAN |
| (192.168.1.0/24) |
+---------------------------+
/ | \
/ | \
+-------+ +---+----+ +---+------+
| Client| | Server | | Database |
+-------+ +--------+ +----------+
- A single Linux server hosting all three firewalld zones
- eth0 configured for the external zone (Internet-facing)
- eth1 configured for the dmz zone (for web services)
- eth2 configured for the internal zone (trusted LAN access)
- The LAN network connected to the internal zone
Basic Configuration Commands
Getting Started
# Check firewalld status
sudo firewall-cmd --state
# List available zones
sudo firewall-cmd --get-zones
# List active zones
sudo firewall-cmd --get-active-zones
# View zone details
sudo firewall-cmd --zone=public --list-all
Managing Network Interfaces
# Assign an interface to a zone
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
# Remove an interface from a zone
sudo firewall-cmd --zone=public --remove-interface=eth1 --permanent
Managing Services
# List predefined services
sudo firewall-cmd --get-services
# Allow a service in a zone
sudo firewall-cmd --zone=public --add-service=http --permanent
# Remove a service from a zone
sudo firewall-cmd --zone=public --remove-service=http --permanent
Managing Ports
# Open a port
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
# Close a port
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
Managing Source IPs
# Allow specific IP address
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
# Remove source IP
sudo firewall-cmd --zone=trusted --remove-source=192.168.1.0/24 --permanent
Applying Changes
# Apply changes (required after --permanent options)
sudo firewall-cmd --reload
Real-World Configuration Example
Let’s configure a server with three network zones:
- external zone (eth0): Internet-facing with limited services
- dmz zone (eth1): For web services with controlled access
- internal zone (eth2): For trusted internal network
# Set interfaces to zones
sudo firewall-cmd --zone=external --change-interface=eth0 --permanent
sudo firewall-cmd --zone=dmz --change-interface=eth1 --permanent
sudo firewall-cmd --zone=internal --change-interface=eth2 --permanent
# Configure external zone (Internet-facing)
sudo firewall-cmd --zone=external --add-service=ssh --permanent
sudo firewall-cmd --zone=external --add-service=https --permanent
sudo firewall-cmd --zone=external --add-masquerade --permanent
# Configure DMZ zone (Web services)
sudo firewall-cmd --zone=dmz --add-service=http --permanent
sudo firewall-cmd --zone=dmz --add-service=https --permanent
sudo firewall-cmd --zone=dmz --add-service=mysql --permanent
sudo firewall-cmd --zone=dmz --add-source=192.168.1.0/24 --permanent
# Configure internal zone (Trusted network)
sudo firewall-cmd --zone=internal --set-target=ACCEPT --permanent
# Apply all changes
sudo firewall-cmd --reload
# Verify the configuration
sudo firewall-cmd --list-all-zones
Advanced Configuration Tips
Creating Custom Services
# Create a new service
sudo firewall-cmd --permanent --new-service=myapp
# Add details to the service
sudo firewall-cmd --permanent --service=myapp --set-description="My Custom Application"
sudo firewall-cmd --permanent --service=myapp --add-port=9000/tcp
sudo firewall-cmd --permanent --service=myapp --add-port=9001/udp
# Add the service to a zone
sudo firewall-cmd --zone=public --add-service=myapp --permanent
sudo firewall-cmd --reload
Port Forwarding
# Forward external port 80 to internal server at 192.168.1.10:8080
sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.10 --permanent
sudo firewall-cmd --reload
Troubleshooting firewalld
Common Issues and Solutions
Service Won’t Start
# Check for errors
sudo systemctl status firewalld
sudo journalctl -u firewalld
# Reset to default configuration
sudo cp /usr/lib/firewalld/firewalld.conf /etc/firewalld/
Rules Not Taking Effect
# Make sure you're using --permanent and reloading
sudo firewall-cmd --add-service=http --zone=public --permanent
sudo firewall-cmd --reload
# Check if the rule was applied
sudo firewall-cmd --zone=public --list-all
Connection Issues
# Temporarily disable firewalld for testing
sudo systemctl stop firewalld
# If connection works now, gradually re-enable services
# Debug with logging
sudo firewall-cmd --set-log-denied=all
sudo firewall-cmd --reload
# Then check logs with:
sudo journalctl -f
Conflicting Firewall Systems
# Check if other firewall services are running
sudo systemctl status iptables
sudo systemctl status ufw
# Disable other firewalls if needed
sudo systemctl disable iptables
sudo systemctl stop iptables
sudo systemctl disable ufw
sudo systemctl stop ufw
Best Practices of Firewalld
Here are some tips to help you maintain a secure and manageable Firewalld setup:
- Start with the
drop
zone and allow only what’s needed. This is a security-first approach. - Assign interfaces thoughtfully. Bind trusted interfaces (like LAN) to zones like
internal
, and untrusted ones (like WAN) topublic
. - Prefer services over ports to improve readability and reduce manual errors.
- Audit zones regularly using
--list-all
or--list-all-zones
to understand your current configuration. - Be cautious with
--permanent
. Test changes at runtime first, and only persist once validated. - Use automation tools like Ansible or shell scripts for consistent deployments.
- Avoid over-complication. Use rich rules only when basic services or port settings aren’t sufficient.
Final Thoughts
Firewalld brings flexibility and clarity to Linux firewall management, especially for systems with multiple zones or changing network conditions. Compared to iptables
and ufw
, it strikes a strong balance between power and simplicity:
Feature | iptables | ufw | firewalld |
---|---|---|---|
Rule-based | ✅ | ❌ | ❌ |
Profile-based | ❌ | ✅ | ❌ |
Zone-based | ❌ | ❌ | ✅ |
Rich Rules | 🔧 | ❌ | ✅ |
Runtime Changes | ⚠️ (manual) | ❌ | ✅ (dynamic) |
Backend Support | ✅ | ✅ | ✅ (nftables , iptables ) |
If you’re managing a server that requires dynamic adjustments or needs to separate trust levels between interfaces, Firewalld is a modern solution worth considering.
Further Reading
- 🔗 Official Firewalld Documentation
- 📘
man firewalld
,man firewall-cmd
- 📄 RHEL/CentOS Admin Guides on Firewalld
0 Comments