🔐 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