Sandbox99 Chronicles

Secure Your Linux Server with Firewalld – A Practical Overview

firewalld blog

Written by Jose Mendez

Hi, I’m Jose Mendez, the creator of sandbox99.cc. with a passion for technology and a hands-on approach to learning, I’ve spent more than fifteen years navigating the ever-evolving world of IT.

Published Apr 5, 2025

Reading Time: 5 minutes

🔐 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:

  1. external zone (eth0): Internet-facing with limited services
  2. dmz zone (eth1): For web services with controlled access
  3. 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) to public.
  • 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:

Featureiptablesufwfirewalld
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

Related Post

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.